From a39531edce1c59e18c1f5b77e62cf77ac5e43ef2 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 11 Jul 2023 11:21:43 +0200 Subject: [PATCH 01/97] [ML] Explain Log Rate Spikes: Reenable API integration tests. (#160180) Fixes #155737. This passed 350 flaky test runner runs, reenabling. These API integration tests were missing from CODEOWNERS, adding that in this PR too (`/x-pack/test/api_integration/apis/aiops/ @elastic/ml-ui`). --- .github/CODEOWNERS | 1 + .../apis/aiops/explain_log_rate_spikes_groups_only.ts | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 23e676132a48c..6ace7d9ba39a4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -913,6 +913,7 @@ x-pack/plugins/infra/server/lib/alerting @elastic/actionable-observability # Additional plugins and packages maintained by the ML team. /x-pack/test/accessibility/apps/transform.ts @elastic/ml-ui +/x-pack/test/api_integration/apis/aiops/ @elastic/ml-ui /x-pack/test/api_integration/apis/transform/ @elastic/ml-ui /x-pack/test/api_integration_basic/apis/transform/ @elastic/ml-ui /x-pack/test/functional/apps/transform/ @elastic/ml-ui diff --git a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_groups_only.ts b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_groups_only.ts index a515af80effd0..41c6df0287254 100644 --- a/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_groups_only.ts +++ b/x-pack/test/api_integration/apis/aiops/explain_log_rate_spikes_groups_only.ts @@ -25,8 +25,7 @@ export default ({ getService }: FtrProviderContext) => { const kibanaServerUrl = formatUrl(config.get('servers.kibana')); const esArchiver = getService('esArchiver'); - // FLAKY: https://github.com/elastic/kibana/issues/155737 - describe.skip('POST /internal/aiops/explain_log_rate_spikes - groups only', () => { + describe('POST /internal/aiops/explain_log_rate_spikes - groups only', () => { explainLogRateSpikesTestData.forEach((testData) => { const overrides = { loaded: 0, From 15a86c355a261ce11cad82f3b3c47dfeca814d1f Mon Sep 17 00:00:00 2001 From: Georgii Gorbachev Date: Tue, 11 Jul 2023 11:27:00 +0200 Subject: [PATCH 02/97] [Security Solution] Move test plans from /cypress to /docs (#161517) **Related to:** https://github.com/elastic/security-team/issues/6867 (internal) ## Summary As requested in https://github.com/elastic/kibana/pull/160685#issuecomment-1621635262. In test plans, we mention how scenarios are going to be automated -- whether a given scenario will be automated using Cypress for e2e tests, Jest for integration tests and unit tests, etc. But currently, test plans are under `x-pack/plugins/security_solution/cypress/`. Since test plans are in fact technology agnostic, it does not make much sense to keep them inside a specific framework technology folder. That's why we're moving them to a generic `x-pack/plugins/security_solution/docs/testing` folder. --- .github/CODEOWNERS | 4 ++-- .../{cypress => docs/testing}/test_plans/README.md | 0 .../prebuilt_rules/installation_and_upgrade.md | 0 .../test_plans/detection_response/rule_management/todo | 0 .../testing}/test_plans/test_plan_template.md | 0 5 files changed, 2 insertions(+), 2 deletions(-) rename x-pack/plugins/security_solution/{cypress => docs/testing}/test_plans/README.md (100%) rename x-pack/plugins/security_solution/{cypress => docs/testing}/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md (100%) rename x-pack/plugins/security_solution/{cypress => docs/testing}/test_plans/detection_response/rule_management/todo (100%) rename x-pack/plugins/security_solution/{cypress => docs/testing}/test_plans/test_plan_template.md (100%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6ace7d9ba39a4..ddb6770c6a756 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1119,8 +1119,8 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib /x-pack/plugins/security_solution/common/detection_engine/rule_monitoring @elastic/security-detection-rule-management /x-pack/plugins/security_solution/common/detection_engine/rule_schema @elastic/security-detection-rule-management @elastic/security-detection-engine -/x-pack/plugins/security_solution/cypress/test_plans/detection_response/prebuilt_rules @elastic/security-detection-rule-management -/x-pack/plugins/security_solution/cypress/test_plans/detection_response/rule_management @elastic/security-detection-rule-management +/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules @elastic/security-detection-rule-management +/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/rule_management @elastic/security-detection-rule-management /x-pack/plugins/security_solution/public/common/components/health_truncate_text @elastic/security-detection-rule-management /x-pack/plugins/security_solution/public/common/components/links_to_docs @elastic/security-detection-rule-management diff --git a/x-pack/plugins/security_solution/cypress/test_plans/README.md b/x-pack/plugins/security_solution/docs/testing/test_plans/README.md similarity index 100% rename from x-pack/plugins/security_solution/cypress/test_plans/README.md rename to x-pack/plugins/security_solution/docs/testing/test_plans/README.md diff --git a/x-pack/plugins/security_solution/cypress/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md b/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md similarity index 100% rename from x-pack/plugins/security_solution/cypress/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md rename to x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md diff --git a/x-pack/plugins/security_solution/cypress/test_plans/detection_response/rule_management/todo b/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/rule_management/todo similarity index 100% rename from x-pack/plugins/security_solution/cypress/test_plans/detection_response/rule_management/todo rename to x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/rule_management/todo diff --git a/x-pack/plugins/security_solution/cypress/test_plans/test_plan_template.md b/x-pack/plugins/security_solution/docs/testing/test_plans/test_plan_template.md similarity index 100% rename from x-pack/plugins/security_solution/cypress/test_plans/test_plan_template.md rename to x-pack/plugins/security_solution/docs/testing/test_plans/test_plan_template.md From bda0195982e346db528ecbb73b1cfd309db49f31 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Tue, 11 Jul 2023 11:51:05 +0200 Subject: [PATCH 03/97] [http] Fix running FTR tests locally (#161336) ## Summary Running FTR tests locally (not on CI) that make API requests to public versioned Kibana endpoints is currently broken. This is because: * we require version headers to be set for both internal and **public** endpoints in **dev** by way of a runtime check (ensures our code is locked to a version) * the vast majority of FTR tests do not set these headers for talking to public endpoints * on CI, this is different as we run these tests against a distributable build (i.e., non-dev) This manifests locally as a 400 response. E.g. the current api_integration tests for data views by running: ``` node scripts/functional_test_runner.js --config ./test/api_integration/config.js --grep 'index_pattern_crud' ``` --- There are a few ways to resolve this, this PR proposes that we: * Keep FTR tests as they are (i.e., don't update all of them to set headers when making requests to public versioned endpoints), this is a useful way to exercise our intended end-user behaviour * Make the version resolution behaviour not depend on `--dev`: rather set the default resolution to `none` (new setting) when we run in `--dev` so that it can be configured to behave as we want for tests. In this way we keep the runtime check for its intended purpose and can run our FTR tests "as end users" of our endpoints. --- Close https://github.com/elastic/kibana/issues/161435 --- .../core-http-router-server-internal/index.ts | 1 + .../src/router.ts | 6 ++-- .../versioned_router/core_versioned_route.ts | 20 +++++------ .../src/versioned_router/handler_resolvers.ts | 5 ++- .../src/versioned_router/index.ts | 1 + .../src/versioned_router/types.ts | 4 ++- .../src/http_config.test.ts | 23 ++++++++++++ .../src/http_config.ts | 35 +++++++++++++++---- .../start_servers/start_servers.ts | 11 +++++- .../http/versioned_router.test.ts | 24 +++++-------- 10 files changed, 93 insertions(+), 37 deletions(-) diff --git a/packages/core/http/core-http-router-server-internal/index.ts b/packages/core/http/core-http-router-server-internal/index.ts index 026c6b854e8bb..1081af2c4aa70 100644 --- a/packages/core/http/core-http-router-server-internal/index.ts +++ b/packages/core/http/core-http-router-server-internal/index.ts @@ -8,6 +8,7 @@ export { filterHeaders } from './src/headers'; export { Router, type RouterOptions } from './src/router'; +export type { HandlerResolutionStrategy } from './src/versioned_router'; export { isKibanaRequest, isRealRequest, ensureRawRequest, CoreKibanaRequest } from './src/request'; export { isSafeMethod } from './src/route'; export { HapiResponseAdapter } from './src/response_adapter'; diff --git a/packages/core/http/core-http-router-server-internal/src/router.ts b/packages/core/http/core-http-router-server-internal/src/router.ts index 509f407ff401a..617c810109138 100644 --- a/packages/core/http/core-http-router-server-internal/src/router.ts +++ b/packages/core/http/core-http-router-server-internal/src/router.ts @@ -124,10 +124,10 @@ export interface RouterOptions { /** Whether we are running in development */ isDev?: boolean; /** - * Which route resolution algo to use - * @default 'oldest' + * Which route resolution algo to use. + * @note default to "oldest", but when running in dev default to "none" */ - versionedRouteResolution?: 'newest' | 'oldest'; + versionedRouteResolution?: 'newest' | 'oldest' | 'none'; } /** diff --git a/packages/core/http/core-http-router-server-internal/src/versioned_router/core_versioned_route.ts b/packages/core/http/core-http-router-server-internal/src/versioned_router/core_versioned_route.ts index 339890fbdddec..dd1a0c21d5593 100644 --- a/packages/core/http/core-http-router-server-internal/src/versioned_router/core_versioned_route.ts +++ b/packages/core/http/core-http-router-server-internal/src/versioned_router/core_versioned_route.ts @@ -71,7 +71,6 @@ export class CoreVersionedRoute implements VersionedRoute { } private isPublic: boolean; - private isInternal: boolean; private enableQueryVersion: boolean; private constructor( private readonly router: CoreVersionedRouter, @@ -81,7 +80,6 @@ export class CoreVersionedRoute implements VersionedRoute { ) { this.isPublic = this.options.access === 'public'; this.enableQueryVersion = this.options.enableQueryVersion === true; - this.isInternal = !this.isPublic; this.router.router[this.method]( { path: this.path, @@ -100,7 +98,7 @@ export class CoreVersionedRoute implements VersionedRoute { } /** This method assumes that one or more versions handlers are registered */ - private getDefaultVersion(): ApiVersion { + private getDefaultVersion(): undefined | ApiVersion { return resolvers[this.router.defaultHandlerResolutionStrategy]([...this.handlers.keys()]); } @@ -120,8 +118,15 @@ export class CoreVersionedRoute implements VersionedRoute { }); } const req = originalReq as Mutable; - const requestVersion = readVersion(req, this.enableQueryVersion); - if (!requestVersion && !this.canUseDefaultVersion()) { + let version: undefined | ApiVersion; + + const maybeVersion = readVersion(req, this.enableQueryVersion); + if (!maybeVersion && this.isPublic) { + version = this.getDefaultVersion(); + } else { + version = maybeVersion; + } + if (!version) { return res.badRequest({ body: `Please specify a version via ${ELASTIC_HTTP_VERSION_HEADER} header. Available versions: ${this.versionsToString()}`, }); @@ -135,7 +140,6 @@ export class CoreVersionedRoute implements VersionedRoute { body: `Use of query parameter "${ELASTIC_HTTP_VERSION_QUERY_PARAM}" is not allowed. Please specify the API version using the "${ELASTIC_HTTP_VERSION_HEADER}" header.`, }); } - const version: ApiVersion = requestVersion ?? this.getDefaultVersion(); const invalidVersionMessage = isValidRouteVersion(this.isPublic, version); if (invalidVersionMessage) { @@ -198,10 +202,6 @@ export class CoreVersionedRoute implements VersionedRoute { ); }; - private canUseDefaultVersion(): boolean { - return !this.isInternal && !this.router.isDev; - } - private validateVersion(version: string) { // We do an additional check here while we only have a single allowed public version // for all public Kibana HTTP APIs diff --git a/packages/core/http/core-http-router-server-internal/src/versioned_router/handler_resolvers.ts b/packages/core/http/core-http-router-server-internal/src/versioned_router/handler_resolvers.ts index 376116c02607b..22f127ff71d95 100644 --- a/packages/core/http/core-http-router-server-internal/src/versioned_router/handler_resolvers.ts +++ b/packages/core/http/core-http-router-server-internal/src/versioned_router/handler_resolvers.ts @@ -10,13 +10,16 @@ * Assumes that there is at least one version in the array. * @internal */ -type Resolver = (versions: string[]) => string; +type Resolver = (versions: string[]) => undefined | string; const oldest: Resolver = (versions) => [...versions].sort((a, b) => a.localeCompare(b))[0]; const newest: Resolver = (versions) => [...versions].sort((a, b) => b.localeCompare(a))[0]; +const none: Resolver = () => undefined; + export const resolvers = { oldest, newest, + none, }; diff --git a/packages/core/http/core-http-router-server-internal/src/versioned_router/index.ts b/packages/core/http/core-http-router-server-internal/src/versioned_router/index.ts index a7d6e9c82fdb6..941b6b5e5706f 100644 --- a/packages/core/http/core-http-router-server-internal/src/versioned_router/index.ts +++ b/packages/core/http/core-http-router-server-internal/src/versioned_router/index.ts @@ -7,3 +7,4 @@ */ export { CoreVersionedRouter } from './core_versioned_router'; +export type { HandlerResolutionStrategy } from './types'; diff --git a/packages/core/http/core-http-router-server-internal/src/versioned_router/types.ts b/packages/core/http/core-http-router-server-internal/src/versioned_router/types.ts index be0471c93848c..4004004036c53 100644 --- a/packages/core/http/core-http-router-server-internal/src/versioned_router/types.ts +++ b/packages/core/http/core-http-router-server-internal/src/versioned_router/types.ts @@ -42,4 +42,6 @@ export type HandlerResolutionStrategy = /** Use the oldest available version by default */ | 'oldest' /** Use the newest available version by default */ - | 'newest'; + | 'newest' + /** Dev-only: remove resolution and fail if no version is provided */ + | 'none'; diff --git a/packages/core/http/core-http-server-internal/src/http_config.test.ts b/packages/core/http/core-http-server-internal/src/http_config.test.ts index 9e9c7febed995..c535bc64fbb00 100644 --- a/packages/core/http/core-http-server-internal/src/http_config.test.ts +++ b/packages/core/http/core-http-server-internal/src/http_config.test.ts @@ -486,6 +486,29 @@ describe('cors', () => { }); }); +describe('versioned', () => { + it('defaults version resolution "oldest" not in dev', () => { + expect(config.schema.validate({}, { dev: undefined })).toMatchObject({ + versioned: { versionResolution: 'oldest' }, + }); + expect(config.schema.validate({}, { dev: false })).toMatchObject({ + versioned: { versionResolution: 'oldest' }, + }); + }); + + it('does not allow "none" when not in dev', () => { + expect(() => + config.schema.validate({ versioned: { versionResolution: 'none' } }, { dev: false }) + ).toThrow(/failed validation/); + }); + + it('defaults version resolution "none" when in dev', () => { + expect(config.schema.validate({}, { dev: true })).toMatchObject({ + versioned: { versionResolution: 'none' }, + }); + }); +}); + describe('HttpConfig', () => { it('converts customResponseHeaders to strings or arrays of strings', () => { const httpSchema = config.schema; diff --git a/packages/core/http/core-http-server-internal/src/http_config.ts b/packages/core/http/core-http-server-internal/src/http_config.ts index 3a96b97b88cbf..d0a3ced0d5fab 100644 --- a/packages/core/http/core-http-server-internal/src/http_config.ts +++ b/packages/core/http/core-http-server-internal/src/http_config.ts @@ -17,6 +17,7 @@ import url from 'url'; import type { Duration } from 'moment'; import { IHttpEluMonitorConfig } from '@kbn/core-http-server/src/elu_monitor'; +import type { HandlerResolutionStrategy } from '@kbn/core-http-router-server-internal'; import { CspConfigType, CspConfig } from './csp'; import { ExternalUrlConfig } from './external_url'; import { @@ -168,11 +169,30 @@ const configSchema = schema.object( ), restrictInternalApis: schema.boolean({ defaultValue: false }), // allow access to internal routes by default to prevent breaking changes in current offerings versioned: schema.object({ - // Which handler resolution algo to use: "newest" or "oldest" - versionResolution: schema.oneOf([schema.literal('newest'), schema.literal('oldest')], { - defaultValue: 'oldest', - }), - // Whether we enforce version checks on client requests + /** + * Which handler resolution algo to use: "newest" or "oldest". + * + * @note in development we have an additional option "none" which is also the default. + * This prevents any fallbacks and requires that a version specified. + * Useful for ensuring that a given client always specifies a version. + */ + versionResolution: schema.conditional( + schema.contextRef('dev'), + true, + schema.oneOf([schema.literal('newest'), schema.literal('oldest'), schema.literal('none')], { + defaultValue: 'none', + }), + schema.oneOf([schema.literal('newest'), schema.literal('oldest')], { + defaultValue: 'oldest', + }) + ), + + /** + * Whether we require the Kibana browser build version to match the Kibana server build version. + * + * This number is determined when a distributable version of Kibana is built and ensures that only + * same-build browsers can access the Kibana server. + */ strictClientVersionCheck: schema.boolean({ defaultValue: true }), }), }, @@ -247,7 +267,10 @@ export class HttpConfig implements IHttpConfig { public externalUrl: IExternalUrlConfig; public xsrf: { disableProtection: boolean; allowlist: string[] }; public requestId: { allowFromAnyIp: boolean; ipAllowlist: string[] }; - public versioned: { versionResolution: 'newest' | 'oldest'; strictClientVersionCheck: boolean }; + public versioned: { + versionResolution: HandlerResolutionStrategy; + strictClientVersionCheck: boolean; + }; public shutdownTimeout: Duration; public restrictInternalApis: boolean; diff --git a/packages/kbn-test/src/functional_tests/start_servers/start_servers.ts b/packages/kbn-test/src/functional_tests/start_servers/start_servers.ts index 8c351db9b42f6..f16b24f59bcf3 100644 --- a/packages/kbn-test/src/functional_tests/start_servers/start_servers.ts +++ b/packages/kbn-test/src/functional_tests/start_servers/start_servers.ts @@ -40,7 +40,16 @@ export async function startServers(log: ToolingLog, options: StartServerOptions) procs, config, installDir: options.installDir, - extraKbnOpts: options.installDir ? [] : ['--dev', '--no-dev-config', '--no-dev-credentials'], + extraKbnOpts: options.installDir + ? [] + : [ + '--dev', + '--no-dev-config', + '--no-dev-credentials', + config.get('serverless') + ? '--server.versioned.versionResolution=newest' + : '--server.versioned.versionResolution=oldest', + ], }); reportTime(runStartTime, 'ready', { diff --git a/src/core/server/integration_tests/http/versioned_router.test.ts b/src/core/server/integration_tests/http/versioned_router.test.ts index 5f41d9813ebcc..986c6c4a32572 100644 --- a/src/core/server/integration_tests/http/versioned_router.test.ts +++ b/src/core/server/integration_tests/http/versioned_router.test.ts @@ -15,7 +15,7 @@ import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { executionContextServiceMock } from '@kbn/core-execution-context-server-mocks'; import { contextServiceMock } from '@kbn/core-http-context-server-mocks'; import { createHttpServer, createConfigService } from '@kbn/core-http-server-mocks'; -import type { HttpService } from '@kbn/core-http-server-internal'; +import type { HttpConfigType, HttpService } from '@kbn/core-http-server-internal'; import type { IRouter } from '@kbn/core-http-server'; import type { CliArgs } from '@kbn/config'; import { ELASTIC_HTTP_VERSION_QUERY_PARAM } from '@kbn/core-http-common'; @@ -30,20 +30,17 @@ describe('Routing versioned requests', () => { async function setupServer(cliArgs: Partial = {}) { logger = loggingSystemMock.create(); await server?.stop(); // stop the already started server + const serverConfig: Partial = { + versioned: { + versionResolution: cliArgs.dev ? 'none' : cliArgs.serverless ? 'newest' : 'oldest', + strictClientVersionCheck: !cliArgs.serverless, + }, + }; server = createHttpServer({ logger, env: createTestEnv({ envOptions: getEnvOptions({ cliArgs }) }), configService: createConfigService({ - // We manually sync the config in our mock at this point - server: - cliArgs.serverless === true - ? { - versioned: { - versionResolution: 'newest', - strictClientVersionCheck: false, - }, - } - : undefined, + server: serverConfig, }), }); await server.preboot({ context: contextServiceMock.createPrebootContract() }); @@ -316,10 +313,7 @@ describe('Routing versioned requests', () => { path: '/my-path', access: 'public', }) - .addVersion( - { version: '2023-10-31', validate: { response: { 200: { body: schema.number() } } } }, - async (ctx, req, res) => res.ok() - ); + .addVersion({ version: '2023-10-31', validate: false }, async (ctx, req, res) => res.ok()); await server.start(); await expect( From ba539d7a39a47f558c48adad4a397f4ae3d456d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Tue, 11 Jul 2023 12:02:51 +0200 Subject: [PATCH 04/97] [Defend Workflows] Use Vagrant for real agent Cypress e2e (#160050) ## Summary Run Real Endpoint Cypress E2E on CI using Vagrant --------- Co-authored-by: Tomasz Ciecierski Co-authored-by: Ashokaditya --- .buildkite/ftr_configs.yml | 1 - .../pull_request/defend_workflows.yml | 16 ++ .../steps/functional/common_cypress.sh | 4 + .../steps/functional/defend_workflows.sh | 5 +- .../functional/defend_workflows_vagrant.sh | 14 ++ .../steps/functional/osquery_cypress.sh | 5 +- .../scripts/steps/functional/response_ops.sh | 5 +- .../steps/functional/response_ops_cases.sh | 5 +- .../steps/functional/security_solution.sh | 5 +- .../functional/security_solution_explore.sh | 6 +- .../security_solution_investigations.sh | 6 +- .../steps/functional/threat_intelligence.sh | 5 +- src/dev/precommit_hook/casing_check_config.js | 1 + .../jenkins_defend_workflows_cypress.sh | 14 -- x-pack/plugins/security_solution/package.json | 4 +- .../public/management/cypress/README.md | 165 +++++++++++--- .../cypress/e2e/endpoint/artifacts.cy.ts | 55 ++++- .../endpoint/automated_response_actions.cy.ts | 81 ++++--- .../e2e/endpoint/endpoint_alerts.cy.ts | 2 +- .../cypress/e2e/endpoint/endpoints.cy.ts | 63 +++++- .../cypress/e2e/endpoint/isolate.cy.ts | 169 ++++++-------- .../e2e/endpoint/response_console.cy.ts | 56 ++--- .../cypress/e2e/mocked_data/artifacts.cy.ts | 7 +- .../e2e/mocked_data/endpoint_role_rbac.cy.ts | 3 +- .../cypress/e2e/mocked_data/endpoints.cy.ts | 4 +- .../cypress/e2e/mocked_data/isolate.cy.ts | 7 +- .../mocked_data/reponse_actions_history.cy.ts | 3 +- .../cypress/e2e/mocked_data/responder.cy.ts | 5 +- .../management/cypress/screens/alerts.ts | 3 +- .../management/cypress/screens/endpoints.ts | 13 +- .../management/cypress/screens/fleet.ts | 9 +- .../cypress/screens/policy_details.ts | 4 +- .../cypress/support/data_loaders.ts | 87 ++++++-- .../management/cypress/tasks/api_fixtures.ts | 3 +- .../public/management/cypress/tasks/common.ts | 23 +- .../cypress/tasks/create_endpoint_host.ts | 2 +- .../management/cypress/tasks/isolate.ts | 9 +- .../public/management/cypress/tasks/login.ts | 4 +- .../management/cypress/tasks/navigation.ts | 3 +- .../cypress/tasks/response_actions.ts | 8 +- .../cypress/tasks/response_console.ts | 3 +- .../management/cypress_endpoint.config.ts | 2 + .../endpoint/common/endpoint_host_services.ts | 206 +++++++++++++----- .../endpoint_agent_runner/Vagrantfile | 29 +++ .../endpoint_agent_runner/elastic_endpoint.ts | 24 +- .../endpoint_agent_runner/fleet_server.ts | 11 - .../endpoint/endpoint_agent_runner/runtime.ts | 1 + .../endpoint/endpoint_agent_runner/types.ts | 1 + .../scripts/run_cypress/parallel.ts | 10 +- x-pack/test/defend_workflows_cypress/agent.ts | 37 ---- .../test/defend_workflows_cypress/config.ts | 1 - .../endpoint_config.ts | 4 +- .../defend_workflows_cypress/fleet_server.ts | 43 ---- .../resource_manager.ts | 15 -- .../test/defend_workflows_cypress/runner.ts | 66 +----- x-pack/test/defend_workflows_cypress/utils.ts | 39 ---- .../defend_workflows_cypress/visual_config.ts | 19 -- x-pack/test/osquery_cypress/runner.ts | 2 +- x-pack/test/osquery_cypress/utils.ts | 31 +++ 59 files changed, 802 insertions(+), 626 deletions(-) create mode 100644 .buildkite/scripts/steps/functional/common_cypress.sh create mode 100755 .buildkite/scripts/steps/functional/defend_workflows_vagrant.sh delete mode 100755 test/scripts/jenkins_defend_workflows_cypress.sh create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/Vagrantfile delete mode 100644 x-pack/test/defend_workflows_cypress/agent.ts delete mode 100644 x-pack/test/defend_workflows_cypress/fleet_server.ts delete mode 100644 x-pack/test/defend_workflows_cypress/resource_manager.ts delete mode 100644 x-pack/test/defend_workflows_cypress/utils.ts delete mode 100644 x-pack/test/defend_workflows_cypress/visual_config.ts diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index f6164da4ac206..fcba384a9844d 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -28,7 +28,6 @@ disabled: - x-pack/test/defend_workflows_cypress/cli_config.ts - x-pack/test/defend_workflows_cypress/config.ts - x-pack/test/defend_workflows_cypress/endpoint_config.ts - - x-pack/test/defend_workflows_cypress/visual_config.ts - x-pack/plugins/observability_onboarding/e2e/ftr_config_open.ts - x-pack/plugins/observability_onboarding/e2e/ftr_config_runner.ts - x-pack/plugins/observability_onboarding/e2e/ftr_config.ts diff --git a/.buildkite/pipelines/pull_request/defend_workflows.yml b/.buildkite/pipelines/pull_request/defend_workflows.yml index 06a4c386b472a..22be5122727bf 100644 --- a/.buildkite/pipelines/pull_request/defend_workflows.yml +++ b/.buildkite/pipelines/pull_request/defend_workflows.yml @@ -14,3 +14,19 @@ steps: limit: 1 artifact_paths: - "target/kibana-security-solution/**/*" + + - command: .buildkite/scripts/steps/functional/defend_workflows_vagrant.sh + label: 'Defend Workflows Endpoint Cypress Tests' + agents: + queue: n2-16-virt + depends_on: build + timeout_in_minutes: 120 + parallelism: 6 + retry: + automatic: + - exit_status: '-1' + limit: 3 + - exit_status: '*' + limit: 1 + artifact_paths: + - "target/kibana-security-solution/**/*" diff --git a/.buildkite/scripts/steps/functional/common_cypress.sh b/.buildkite/scripts/steps/functional/common_cypress.sh new file mode 100644 index 0000000000000..4f92cfb683eab --- /dev/null +++ b/.buildkite/scripts/steps/functional/common_cypress.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +Xvfb -screen 0 1680x946x24 :99 & +export DISPLAY=:99 diff --git a/.buildkite/scripts/steps/functional/defend_workflows.sh b/.buildkite/scripts/steps/functional/defend_workflows.sh index d2a06a1932b8a..039d25d2ed8a8 100755 --- a/.buildkite/scripts/steps/functional/defend_workflows.sh +++ b/.buildkite/scripts/steps/functional/defend_workflows.sh @@ -3,14 +3,11 @@ set -euo pipefail source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/steps/functional/common_cypress.sh export JOB=kibana-defend-workflows-cypress export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} -Xvfb -screen 0 1680x946x24 :99 & - -export DISPLAY=:99 - echo "--- Defend Workflows Cypress tests" yarn --cwd x-pack/plugins/security_solution cypress:dw:run diff --git a/.buildkite/scripts/steps/functional/defend_workflows_vagrant.sh b/.buildkite/scripts/steps/functional/defend_workflows_vagrant.sh new file mode 100755 index 0000000000000..a99cf0e86f4ec --- /dev/null +++ b/.buildkite/scripts/steps/functional/defend_workflows_vagrant.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -euo pipefail + +source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/steps/functional/common_cypress.sh + +export JOB=kibana-defend-workflows-endpoint-cypress +export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} + + +echo "--- Defend Workflows Endpoint Cypress tests" + +yarn --cwd x-pack/plugins/security_solution cypress:dw:endpoint:run diff --git a/.buildkite/scripts/steps/functional/osquery_cypress.sh b/.buildkite/scripts/steps/functional/osquery_cypress.sh index ecabf52e3c14d..c6cc98d71ce07 100755 --- a/.buildkite/scripts/steps/functional/osquery_cypress.sh +++ b/.buildkite/scripts/steps/functional/osquery_cypress.sh @@ -3,14 +3,11 @@ set -euo pipefail source .buildkite/scripts/common/util.sh +source .buildkite/scripts/steps/functional/common_cypress.sh .buildkite/scripts/bootstrap.sh node scripts/build_kibana_platform_plugins.js -Xvfb :99 -screen 0 1600x1200x24 & - -export DISPLAY=:99 - export JOB=kibana-osquery-cypress echo "--- Osquery Cypress tests" diff --git a/.buildkite/scripts/steps/functional/response_ops.sh b/.buildkite/scripts/steps/functional/response_ops.sh index 066a1b599fd93..6e61ac3b65ed9 100755 --- a/.buildkite/scripts/steps/functional/response_ops.sh +++ b/.buildkite/scripts/steps/functional/response_ops.sh @@ -3,14 +3,11 @@ set -euo pipefail source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/steps/functional/common_cypress.sh export JOB=kibana-security-solution-chrome export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} -Xvfb -screen 0 1680x946x24 :99 & - -export DISPLAY=:99 - echo "--- Response Ops Cypress Tests on Security Solution" yarn --cwd x-pack/plugins/security_solution cypress:run:respops diff --git a/.buildkite/scripts/steps/functional/response_ops_cases.sh b/.buildkite/scripts/steps/functional/response_ops_cases.sh index d838307af63c7..07a736d0c2342 100755 --- a/.buildkite/scripts/steps/functional/response_ops_cases.sh +++ b/.buildkite/scripts/steps/functional/response_ops_cases.sh @@ -3,14 +3,11 @@ set -euo pipefail source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/steps/functional/common_cypress.sh export JOB=kibana-security-solution-chrome export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} -Xvfb -screen 0 1680x946x24 :99 & - -export DISPLAY=:99 - echo "--- Response Ops Cases Cypress Tests on Security Solution" yarn --cwd x-pack/plugins/security_solution cypress:run:cases diff --git a/.buildkite/scripts/steps/functional/security_solution.sh b/.buildkite/scripts/steps/functional/security_solution.sh index 078c9af1363c6..f021cdc7c8fc3 100755 --- a/.buildkite/scripts/steps/functional/security_solution.sh +++ b/.buildkite/scripts/steps/functional/security_solution.sh @@ -3,14 +3,11 @@ set -euo pipefail source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/steps/functional/common_cypress.sh export JOB=kibana-security-solution-chrome export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} -Xvfb :99 -screen 0 1600x1200x24 & - -export DISPLAY=:99 - echo "--- Security Solution tests (Chrome)" yarn --cwd x-pack/plugins/security_solution cypress:run diff --git a/.buildkite/scripts/steps/functional/security_solution_explore.sh b/.buildkite/scripts/steps/functional/security_solution_explore.sh index cc5010602e6fc..6a13b09d15167 100644 --- a/.buildkite/scripts/steps/functional/security_solution_explore.sh +++ b/.buildkite/scripts/steps/functional/security_solution_explore.sh @@ -3,15 +3,11 @@ set -euo pipefail source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/steps/functional/common_cypress.sh export JOB=kibana-security-solution-chrome export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} - -Xvfb :99 -screen 0 1600x1200x24 & - -export DISPLAY=:99 - echo "--- Explore Cypress Tests on Security Solution" yarn --cwd x-pack/plugins/security_solution cypress:explore:run diff --git a/.buildkite/scripts/steps/functional/security_solution_investigations.sh b/.buildkite/scripts/steps/functional/security_solution_investigations.sh index 9c6138d335405..e5685ac9dcb51 100644 --- a/.buildkite/scripts/steps/functional/security_solution_investigations.sh +++ b/.buildkite/scripts/steps/functional/security_solution_investigations.sh @@ -3,15 +3,11 @@ set -euo pipefail source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/steps/functional/common_cypress.sh export JOB=kibana-security-solution-chrome export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} - -Xvfb :99 -screen 0 1600x1200x24 & - -export DISPLAY=:99 - echo "--- Investigations Cypress Tests on Security Solution" yarn --cwd x-pack/plugins/security_solution cypress:investigations:run diff --git a/.buildkite/scripts/steps/functional/threat_intelligence.sh b/.buildkite/scripts/steps/functional/threat_intelligence.sh index 7da06f7ed9331..c07ea8605c2d0 100755 --- a/.buildkite/scripts/steps/functional/threat_intelligence.sh +++ b/.buildkite/scripts/steps/functional/threat_intelligence.sh @@ -3,14 +3,11 @@ set -euo pipefail source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/steps/functional/common_cypress.sh export JOB=kibana-threat-intelligence-chrome export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} -Xvfb :99 -screen 0 1600x1200x24 & - -export DISPLAY=:99 - echo "--- Threat Intelligence tests (Chrome)" yarn --cwd x-pack/plugins/threat_intelligence cypress:run diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index c07b30a45ef3b..45fdb283910b4 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -44,6 +44,7 @@ export const IGNORE_FILE_GLOBS = [ 'packages/kbn-test/jest-preset.js', 'packages/kbn-test/*/jest-preset.js', 'test/package/Vagrantfile', + 'x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/Vagrantfile', '**/test/**/fixtures/**/*', // Required to match the name in the docs.elastic.dev repo. diff --git a/test/scripts/jenkins_defend_workflows_cypress.sh b/test/scripts/jenkins_defend_workflows_cypress.sh deleted file mode 100755 index 755c3093d4fc8..0000000000000 --- a/test/scripts/jenkins_defend_workflows_cypress.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -echo " -> Running defend workflows cypress tests" -cd "$XPACK_DIR" - -node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --config test/defend_workflows_cypress/cli_config.ts - -echo "" -echo "" diff --git a/x-pack/plugins/security_solution/package.json b/x-pack/plugins/security_solution/package.json index 9cfd8444dc04b..e5f6125107859 100644 --- a/x-pack/plugins/security_solution/package.json +++ b/x-pack/plugins/security_solution/package.json @@ -21,8 +21,8 @@ "cypress:run:upgrade": "yarn cypress:run:reporter --browser chrome --config specPattern=./cypress/upgrade_e2e/**/*.cy.ts", "cypress:dw:open": "node ./scripts/start_cypress_parallel open --config-file ./public/management/cypress.config.ts ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/cli_config", "cypress:dw:run": "node ./scripts/start_cypress_parallel run --config-file ./public/management/cypress.config.ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/cli_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json; status=$?; yarn junit:merge && exit $status", - "cypress:dw:endpoint:open": "yarn cypress open --config-file ./public/management/cypress_endpoint.config.ts", - "cypress:dw:endpoint:open-as-ci": "node ../../../scripts/functional_tests --config ../../test/defend_workflows_cypress/endpoint_config.ts", + "cypress:dw:endpoint:run": "node ./scripts/start_cypress_parallel run --config-file ./public/management/cypress_endpoint.config.ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/endpoint_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json --concurrency 1; status=$?; yarn junit:merge && exit $status", + "cypress:dw:endpoint:open": "node ./scripts/start_cypress_parallel open --config-file ./public/management/cypress_endpoint.config.ts ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/endpoint_config", "cypress:investigations:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/investigations/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", "cypress:explore:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/explore/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", "junit:merge": "../../../node_modules/.bin/mochawesome-merge ../../../target/kibana-security-solution/cypress/results/mochawesome*.json > ../../../target/kibana-security-solution/cypress/results/output.json && ../../../node_modules/.bin/marge ../../../target/kibana-security-solution/cypress/results/output.json --reportDir ../../../target/kibana-security-solution/cypress/results && mkdir -p ../../../target/junit && cp ../../../target/kibana-security-solution/cypress/results/*.xml ../../../target/junit/", diff --git a/x-pack/plugins/security_solution/public/management/cypress/README.md b/x-pack/plugins/security_solution/public/management/cypress/README.md index 331a68382ebb5..ba9f0d80859cb 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/README.md +++ b/x-pack/plugins/security_solution/public/management/cypress/README.md @@ -1,14 +1,43 @@ # Cypress Tests -The `management/cypress` directory contains functional UI tests that execute using [Cypress](https://www.cypress.io/). +The `plugins/security_solution/public/management/cypress` directory contains functional UI tests that execute +using [Cypress](https://www.cypress.io/). + +## Pre-requisites + +Good to have before you run the tests: + +- Docker CLI, as Docker desktop doesn't install it by default. Install using `brew`: + +```shell +brew install docker +``` + +- [Multipass](https://multipass.run/) for running the tests against real endpoint. Install using `brew`: + +```shell +brew install multipass +``` + +If you also want to run the tests against real endpoints as on the CI pipeline, then you need to have the following: + +- [Vagrant](https://developer.hashicorp.com/vagrant/docs/installation) +- [Vagrant provider for VMware](https://developer.hashicorp.com/vagrant/docs/providers/vmware/installation) +- [Vagrant VMware Utility](https://developer.hashicorp.com/vagrant/docs/providers/vmware/vagrant-vmware-utility) +- [VMware Fusion](https://www.vmware.com/products/fusion/fusion-evaluation.html) + +See [running interactive tests on real endpoint with vagrant](#cypress-interactive-with-real-endpoints-using-vagrant) +for more information. ## Running the tests -There are currently three ways to run the tests, comprised of two execution modes and two target environments, which will be detailed below. +There are currently three ways to run the tests, comprised of two execution modes and two target environments, which +will be detailed below. ### Environment Variables -The test suites are setup with defaults for Kibana and Elasticsearch. The following environment variables can be set to changes those defaults and target a run against different instances of the stack: +The test suites are set up with defaults for Kibana and Elasticsearch. The following environment variables can be set to +changes those defaults and target a run against different instances of the stack: ``` CYPRESS_KIBANA_URL @@ -27,68 +56,143 @@ Some notes: Example: ```shell -cd /x-pack/plugins/security_solution +yarn --cwd x-pack/plugins/security_solution CYPRESS_BASE_URL=http://localhost:5601 \ CYPRESS_KIBANA_URL=http://localhost:5601 \ CYPRESS_ELASTICSEARCH_USERNAME=elastic \ CYPRESS_ELASTICSEARCH_PASSWORD=changeme \ -CYPRESS_ELASTICSEARCH_URL=http://localhost:9200 yarn cypress:dw:open +CYPRESS_ELASTICSEARCH_URL=http://localhost:9200 cypress:dw:open ``` - ### Execution modes #### Interactive mode -When you run Cypress in interactive mode, an interactive runner is displayed that allows you to see commands as they execute while also viewing the application under test. For more information, please see [cypress documentation](https://docs.cypress.io/guides/core-concepts/test-runner.html#Overview). +When you run Cypress in interactive mode, an interactive runner is displayed that allows you to see commands as they +execute while also viewing the application under test. For more information, please +see [cypress documentation](https://docs.cypress.io/guides/core-concepts/test-runner.html#Overview). #### Headless mode -A headless browser is a browser simulation program that does not have a user interface. These programs operate like any other browser but do not display any UI. This is why meanwhile you are executing the tests on this mode you are not going to see the application under test. Just the output of the test is displayed on the terminal once the execution is finished. +A headless browser is a browser simulation program that does not have a user interface. These programs operate like any +other browser but do not display any UI. So when you are executing the tests on this mode you are not +going to see the application under test. Just the output of the test is displayed on the terminal once the execution is +finished. ### Target environments #### FTR (CI) -This is the configuration used by CI. It uses the FTR to spawn both a Kibana instance (http://localhost:5620) and an Elasticsearch instance (http://localhost:9220) with a preloaded minimum set of data (see preceding "Test data" section), and then executes cypress against this stack. You can find this configuration in `x-pack/test/defend_workflows_cypress` +This is the configuration used by CI. It uses the FTR to spawn both a Kibana instance (http://localhost:5620) and an +Elasticsearch instance (http://localhost:9220) with a preloaded minimum set of data (see preceding "Test data" section), +and then executes cypress against this stack. You can find this configuration in `x-pack/test/defend_workflows_cypress` ### Test Execution: Examples -#### FTR + Headless (Chrome) +#### Cypress + Headless (Chrome) -Since this is how tests are run on CI, this will likely be the configuration you want to reproduce failures locally, etc. +Since this is how tests are run on CI, this will likely be the configuration you want to use in order to reproduce +failures locally, etc. ```shell -# bootstrap kibana from the project root -yarn kbn bootstrap - -# build the plugins/assets that cypress will execute against -node scripts/build_kibana_platform_plugins +# bootstrap kibana from the project root and build the plugins/assets that cypress will execute against +yarn kbn bootstrap && node scripts/build_kibana_platform_plugins # launch the cypress test runner cd x-pack/plugins/security_solution yarn cypress:dw:run-as-ci + +# or + +# launch without changing directory from kibana/ +yarn --cwd x-pack/plugins/security_solution cypress:dw:run-as-ci ``` -#### FTR + Interactive -This is the preferred mode for developing new tests. +#### Cypress -```shell -# bootstrap kibana from the project root -yarn kbn bootstrap +This is the preferred mode for developing new tests against mocked data -# build the plugins/assets that cypress will execute against -node scripts/build_kibana_platform_plugins +```shell +# bootstrap kibana from the project root and build the plugins/assets that cypress will execute against +yarn kbn bootstrap && node scripts/build_kibana_platform_plugins # launch the cypress test runner cd x-pack/plugins/security_solution -yarn cypress:dw:open-as-ci +yarn cypress:dw:open + +# or + +# launch without changing directory from kibana/ +yarn --cwd x-pack/plugins/security_solution cypress:dw:open ``` +For developing/debugging tests against real endpoint please use: + +Endpoint tests require [Multipass](https://multipass.run/) to be installed on your machine. + +```shell +# bootstrap kibana from the project root and build the plugins/assets that cypress will execute against +yarn kbn bootstrap && node scripts/build_kibana_platform_plugins + +# launch the cypress test runner with real endpoint +cd x-pack/plugins/security_solution +yarn cypress:dw:endpoint:open + +# or + +# launch without changing directory from kibana/ +yarn --cwd x-pack/plugins/security_solution cypress:dw:endpoint:open +``` + +#### Cypress (interactive) with real Endpoints using Vagrant + +```shell +# bootstrap kibana from the project root and build the plugins/assets that cypress will execute against +yarn kbn bootstrap && node scripts/build_kibana_platform_plugins + +# launch the cypress test runner with real endpoint +cd x-pack/plugins/security_solution +export CI=true +yarn cypress:dw:endpoint:open +```` + Note that you can select the browser you want to use on the top right side of the interactive runner. +#### Cypress against REAL Endpoint + Headless (Chrome) + +This requires some additional setup as mentioned in the [pre-requisites](#pre-requisites) section. + +Endpoint tests require [Multipass](https://multipass.run/) to be installed on your machine. + +```shell +# bootstrap kibana from the project root and build the plugins/assets that cypress will execute against +yarn kbn bootstrap && node scripts/build_kibana_platform_plugins + +# launch the cypress test runner with real endpoint +cd x-pack/plugins/security_solution +yarn cypress:dw:endpoint:run + +# or + +# launch without changing directory from kibana/ +yarn --cwd x-pack/plugins/security_solution cypress:dw:endpoint:run +``` + ## Folder Structure +### e2e/ + +Contains all the tests. Within it are two sub-folders: + +#### cypress/endpoint + +Contains all the tests that are executed against real endpoints. + +#### cypress/mocked_data + +Contains all the tests that are executed against mocked endpoint and run on CI. If you want to add tests that run on CI +then this is where you should add those. + ### integration/ Cypress convention. Contains the specs that are going to be executed. @@ -99,7 +203,8 @@ Cypress convention. Fixtures are used as external pieces of static data when we ### support/ -Cypress convention. As a convenience, by default Cypress will automatically include the plugins file cypress/plugins/index.js before every single spec file it runs. +Cypress convention. As a convenience, by default Cypress will automatically include the plugins file +cypress/plugins/index.js before every single spec file it runs. Directory also holds Cypress Plugins that are then initialized via `setupNodeEvents()` in the Cypress configuration. ### screens/ @@ -112,7 +217,7 @@ Each file inside the screens folder represents a screen in our application. _Tasks_ are functions that may be reused across tests. -Each file inside the tasks folder represents a screen of our application. +Each file inside the tasks folder represents a screen of our application. ## Test data @@ -122,9 +227,10 @@ The data the tests need: ## Development Best Practices -### Clean up the state +### Clean up the state -Remember to clean up the state of the test after its execution. Be mindful of failure scenarios, as well: if your test fails, will it leave the environment in a recoverable state? +Remember to clean up the state of the test after its execution. Be mindful of failure scenarios, as well: if your test +fails, will it leave the environment in a recoverable state? ### Minimize the use of es_archive @@ -143,4 +249,5 @@ Remember that by minimizing the number of times the web page is loaded, we minim ## Linting -Optional linting rules for Cypress and linting setup can be found [here](https://github.com/cypress-io/eslint-plugin-cypress#usage) +Optional linting rules for Cypress and linting setup can be +found [here](https://github.com/cypress-io/eslint-plugin-cypress#usage) diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/artifacts.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/artifacts.cy.ts index dc81a8c6206dd..151e0f6bf233b 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/artifacts.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/artifacts.cy.ts @@ -6,32 +6,57 @@ */ import { recurse } from 'cypress-recurse'; +import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; import { HOST_METADATA_LIST_ROUTE } from '../../../../../common/endpoint/constants'; -import type { MetadataListResponse } from '../../../../../common/endpoint/types'; +import type { MetadataListResponse, PolicyData } from '../../../../../common/endpoint/types'; import { APP_ENDPOINTS_PATH } from '../../../../../common/constants'; import { getArtifactsListTestsData } from '../../fixtures/artifacts_page'; import { removeAllArtifacts } from '../../tasks/artifacts'; -import { loadEndpointDataForEventFiltersIfNeeded } from '../../tasks/load_endpoint_data'; import { login } from '../../tasks/login'; import { performUserActions } from '../../tasks/perform_user_actions'; -import { request } from '../../tasks/common'; -import { yieldEndpointPolicyRevision } from '../../tasks/fleet'; +import { request, loadPage } from '../../tasks/common'; +import { + createAgentPolicyTask, + getEndpointIntegrationVersion, + yieldEndpointPolicyRevision, +} from '../../tasks/fleet'; +import type { CreateAndEnrollEndpointHostResponse } from '../../../../../scripts/endpoint/common/endpoint_host_services'; +import { createEndpointHost } from '../../tasks/create_endpoint_host'; +import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data'; +import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; const yieldAppliedEndpointRevision = (): Cypress.Chainable => request({ method: 'GET', url: HOST_METADATA_LIST_ROUTE, }).then(({ body }) => { - expect(body.data.length).is.lte(1); // during update it can be temporary zero + expect(body.data.length).is.lte(2); // during update it can be temporary zero return Number(body.data?.[0]?.metadata.Endpoint.policy.applied.endpoint_policy_version) ?? -1; }); const parseRevNumber = (revString: string) => Number(revString.match(/\d+/)?.[0]); describe('Artifact pages', () => { + let indexedPolicy: IndexedFleetEndpointPolicyResponse; + let policy: PolicyData; + let createdHost: CreateAndEnrollEndpointHostResponse; + before(() => { + getEndpointIntegrationVersion().then((version) => + createAgentPolicyTask(version).then((data) => { + indexedPolicy = data; + policy = indexedPolicy.integrationPolicies[0]; + + return enableAllPolicyProtections(policy.id).then(() => { + // Create and enroll a new Endpoint host + return createEndpointHost(policy.policy_id).then((host) => { + createdHost = host as CreateAndEnrollEndpointHostResponse; + }); + }); + }) + ); + login(); - loadEndpointDataForEventFiltersIfNeeded(); removeAllArtifacts(); // wait for ManifestManager to pick up artifact changes that happened either here @@ -49,11 +74,23 @@ describe('Artifact pages', () => { beforeEach(() => { login(); - cy.visit(APP_ENDPOINTS_PATH); + loadPage(APP_ENDPOINTS_PATH); }); after(() => { removeAllArtifacts(); + + if (createdHost) { + cy.task('destroyEndpointHost', createdHost); + } + + if (indexedPolicy) { + cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy); + } + + if (createdHost) { + deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] }); + } }); for (const testData of getArtifactsListTestsData()) { @@ -64,7 +101,7 @@ describe('Artifact pages', () => { .invoke('text') .then(parseRevNumber) .then((initialRevisionNumber) => { - cy.visit(`/app/security/administration/${testData.urlPath}`); + loadPage(`/app/security/administration/${testData.urlPath}`); cy.getByTestSubj(`${testData.pagePrefix}-emptyState-addButton`).click(); performUserActions(testData.create.formActions); @@ -75,7 +112,7 @@ describe('Artifact pages', () => { cy.getByTestSubj(checkResult.selector).should('have.text', checkResult.value); } - cy.visit(APP_ENDPOINTS_PATH); + loadPage(APP_ENDPOINTS_PATH); // depends on the 10s auto refresh cy.getByTestSubj('policyListRevNo') diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/automated_response_actions.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/automated_response_actions.cy.ts index abf708d198984..a62e877f018e4 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/automated_response_actions.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/automated_response_actions.cy.ts @@ -5,25 +5,57 @@ * 2.0. */ -import type { Agent } from '@kbn/fleet-plugin/common'; +import type { PolicyData } from '../../../../../common/endpoint/types'; import { APP_ENDPOINTS_PATH } from '../../../../../common/constants'; import { closeAllToasts } from '../../tasks/toasts'; import { toggleRuleOffAndOn, visitRuleAlerts } from '../../tasks/isolate'; import { cleanupRule, loadRule } from '../../tasks/api_fixtures'; -import { ENDPOINT_VM_NAME } from '../../tasks/common'; import { login } from '../../tasks/login'; +import { loadPage } from '../../tasks/common'; import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; -import { - createAgentPolicyTask, - getAgentByHostName, - getEndpointIntegrationVersion, - reassignAgentPolicy, -} from '../../tasks/fleet'; +import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../tasks/fleet'; import { changeAlertsFilter } from '../../tasks/alerts'; +import type { CreateAndEnrollEndpointHostResponse } from '../../../../../scripts/endpoint/common/endpoint_host_services'; +import { createEndpointHost } from '../../tasks/create_endpoint_host'; +import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data'; +import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; describe('Automated Response Actions', () => { - const endpointHostname = Cypress.env(ENDPOINT_VM_NAME); - const hostname = Cypress.env('hostname'); + let indexedPolicy: IndexedFleetEndpointPolicyResponse; + let policy: PolicyData; + let createdHost: CreateAndEnrollEndpointHostResponse; + + before(() => { + getEndpointIntegrationVersion().then((version) => + createAgentPolicyTask(version, 'automated_response_actions').then((data) => { + indexedPolicy = data; + policy = indexedPolicy.integrationPolicies[0]; + + return enableAllPolicyProtections(policy.id).then(() => { + // Create and enroll a new Endpoint host + return createEndpointHost(policy.policy_id).then((host) => { + createdHost = host as CreateAndEnrollEndpointHostResponse; + }); + }); + }) + ); + }); + + after(() => { + if (createdHost) { + cy.task('destroyEndpointHost', createdHost); + } + + if (indexedPolicy) { + cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy); + } + + if (createdHost) { + deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] }); + } + }); + + const hostname = new URL(Cypress.env('FLEET_SERVER_URL')).port; const fleetHostname = `dev-fleet-server.${hostname}`; beforeEach(() => { @@ -31,47 +63,28 @@ describe('Automated Response Actions', () => { }); describe('From alerts', () => { - let response: IndexedFleetEndpointPolicyResponse; - let initialAgentData: Agent; let ruleId: string; let ruleName: string; before(() => { - getAgentByHostName(endpointHostname).then((agentData) => { - initialAgentData = agentData; - }); - - getEndpointIntegrationVersion().then((version) => { - createAgentPolicyTask(version).then((data) => { - response = data; - }); - }); - loadRule(true).then((data) => { + loadRule().then((data) => { ruleId = data.id; ruleName = data.name; }); }); after(() => { - if (initialAgentData?.policy_id) { - reassignAgentPolicy(initialAgentData.id, initialAgentData.policy_id); - } - if (response) { - cy.task('deleteIndexedFleetEndpointPolicies', response); - } if (ruleId) { cleanupRule(ruleId); } }); it('should have generated endpoint and rule', () => { - cy.visit(APP_ENDPOINTS_PATH); - cy.contains(endpointHostname).should('exist'); + loadPage(APP_ENDPOINTS_PATH); + cy.contains(createdHost.hostname).should('exist'); toggleRuleOffAndOn(ruleName); - }); - it('should display endpoint automated response action in event details flyout ', () => { visitRuleAlerts(ruleName); closeAllToasts(); @@ -80,9 +93,9 @@ describe('Automated Response Actions', () => { cy.getByTestSubj('responseActionsViewTab').click(); cy.getByTestSubj('response-actions-notification').should('not.have.text', '0'); - cy.getByTestSubj(`response-results-${endpointHostname}-details-tray`) + cy.getByTestSubj(`response-results-${createdHost.hostname}-details-tray`) .should('contain', 'isolate completed successfully') - .and('contain', endpointHostname); + .and('contain', createdHost.hostname); cy.getByTestSubj(`response-results-${fleetHostname}-details-tray`) .should('contain', 'The host does not have Elastic Defend integration installed') diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/endpoint_alerts.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/endpoint_alerts.cy.ts index 5b6348c60c6ca..5a33371754be5 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/endpoint_alerts.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/endpoint_alerts.cy.ts @@ -42,7 +42,7 @@ describe('Endpoint generated alerts', () => { after(() => { if (createdHost) { - cy.task('destroyEndpointHost', createdHost).then(() => {}); + cy.task('destroyEndpointHost', createdHost); } if (indexedPolicy) { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/endpoints.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/endpoints.cy.ts index 0937b4a1119f0..d86fabde64a18 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/endpoints.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/endpoints.cy.ts @@ -6,8 +6,8 @@ */ import type { Agent } from '@kbn/fleet-plugin/common'; +import type { PolicyData } from '../../../../../common/endpoint/types'; import { APP_ENDPOINTS_PATH } from '../../../../../common/constants'; -import { ENDPOINT_VM_NAME } from '../../tasks/common'; import { createAgentPolicyTask, getAgentByHostName, @@ -16,6 +16,7 @@ import { } from '../../tasks/fleet'; import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; import { login } from '../../tasks/login'; +import { loadPage } from '../../tasks/common'; import { AGENT_HOSTNAME_CELL, TABLE_ROW_ACTIONS, @@ -26,18 +27,56 @@ import { FLEET_REASSIGN_POLICY_MODAL, FLEET_REASSIGN_POLICY_MODAL_CONFIRM_BUTTON, } from '../../screens/fleet'; +import type { CreateAndEnrollEndpointHostResponse } from '../../../../../scripts/endpoint/common/endpoint_host_services'; +import { createEndpointHost } from '../../tasks/create_endpoint_host'; +import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data'; +import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; describe('Endpoints page', () => { - const endpointHostname = Cypress.env(ENDPOINT_VM_NAME); + let indexedPolicy: IndexedFleetEndpointPolicyResponse; + let policy: PolicyData; + let createdHost: CreateAndEnrollEndpointHostResponse; + + before(() => { + getEndpointIntegrationVersion().then((version) => { + createAgentPolicyTask(version).then((data) => { + indexedPolicy = data; + policy = indexedPolicy.integrationPolicies[0]; + + return enableAllPolicyProtections(policy.id).then(() => { + // Create and enroll a new Endpoint host + return createEndpointHost(policy.policy_id).then((host) => { + createdHost = host as CreateAndEnrollEndpointHostResponse; + }); + }); + }); + }); + }); + + after(() => { + if (createdHost) { + cy.task('destroyEndpointHost', createdHost); + } + + if (indexedPolicy) { + cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy); + } + + if (createdHost) { + deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] }); + } + }); beforeEach(() => { login(); }); it('Shows endpoint on the list', () => { - cy.visit(APP_ENDPOINTS_PATH); + loadPage(APP_ENDPOINTS_PATH); cy.contains('Hosts running Elastic Defend').should('exist'); - cy.getByTestSubj(AGENT_HOSTNAME_CELL).should('have.text', endpointHostname); + cy.getByTestSubj(AGENT_HOSTNAME_CELL) + .contains(createdHost.hostname) + .should('have.text', createdHost.hostname); }); describe('Endpoint reassignment', () => { @@ -45,7 +84,7 @@ describe('Endpoints page', () => { let initialAgentData: Agent; before(() => { - getAgentByHostName(endpointHostname).then((agentData) => { + getAgentByHostName(createdHost.hostname).then((agentData) => { initialAgentData = agentData; }); getEndpointIntegrationVersion().then((version) => { @@ -69,24 +108,24 @@ describe('Endpoints page', () => { }); it('User can reassign a single endpoint to a different Agent Configuration', () => { - cy.visit(APP_ENDPOINTS_PATH); + loadPage(APP_ENDPOINTS_PATH); const hostname = cy .getByTestSubj(AGENT_HOSTNAME_CELL) - .filter(`:contains("${endpointHostname}")`); + .filter(`:contains("${createdHost.hostname}")`); const tableRow = hostname.parents('tr'); - tableRow.getByTestSubj(TABLE_ROW_ACTIONS).click(); + tableRow.findByTestSubj(TABLE_ROW_ACTIONS).click(); cy.getByTestSubj(TABLE_ROW_ACTIONS_MENU).contains('Reassign agent policy').click(); cy.getByTestSubj(FLEET_REASSIGN_POLICY_MODAL) .find('select') .select(response.agentPolicies[0].name); cy.getByTestSubj(FLEET_REASSIGN_POLICY_MODAL_CONFIRM_BUTTON).click(); cy.getByTestSubj(AGENT_HOSTNAME_CELL) - .filter(`:contains("${endpointHostname}")`) + .filter(`:contains("${createdHost.hostname}")`) .should('exist'); cy.getByTestSubj(AGENT_HOSTNAME_CELL) - .filter(`:contains("${endpointHostname}")`) + .filter(`:contains("${createdHost.hostname}")`) .parents('tr') - .getByTestSubj(AGENT_POLICY_CELL) + .findByTestSubj(AGENT_POLICY_CELL) .should('have.text', response.agentPolicies[0].name); }); }); @@ -94,7 +133,7 @@ describe('Endpoints page', () => { it('should update endpoint policy on Endpoint', () => { const parseRevNumber = (revString: string) => Number(revString.match(/\d+/)?.[0]); - cy.visit(APP_ENDPOINTS_PATH); + loadPage(APP_ENDPOINTS_PATH); cy.getByTestSubj('policyListRevNo') .first() diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/isolate.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/isolate.cy.ts index dbf5f89fcb389..ff4adacc9b73f 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/isolate.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/isolate.cy.ts @@ -5,14 +5,13 @@ * 2.0. */ -import type { Agent } from '@kbn/fleet-plugin/common'; +import type { PolicyData } from '../../../../../common/endpoint/types'; import { APP_CASES_PATH, APP_ENDPOINTS_PATH } from '../../../../../common/constants'; import { closeAllToasts } from '../../tasks/toasts'; import { checkEndpointListForOnlyIsolatedHosts, checkEndpointListForOnlyUnIsolatedHosts, checkFlyoutEndpointIsolation, - filterOutEndpoints, filterOutIsolatedHosts, isolateHostWithComment, openAlertDetails, @@ -23,53 +22,63 @@ import { waitForReleaseOption, } from '../../tasks/isolate'; import { cleanupCase, cleanupRule, loadCase, loadRule } from '../../tasks/api_fixtures'; -import { ENDPOINT_VM_NAME } from '../../tasks/common'; import { login } from '../../tasks/login'; +import { loadPage } from '../../tasks/common'; import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; -import { - createAgentPolicyTask, - getAgentByHostName, - getEndpointIntegrationVersion, - reassignAgentPolicy, -} from '../../tasks/fleet'; +import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../tasks/fleet'; +import type { CreateAndEnrollEndpointHostResponse } from '../../../../../scripts/endpoint/common/endpoint_host_services'; +import { createEndpointHost } from '../../tasks/create_endpoint_host'; +import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data'; +import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; describe('Isolate command', () => { - const endpointHostname = Cypress.env(ENDPOINT_VM_NAME); - const isolateComment = `Isolating ${endpointHostname}`; - const releaseComment = `Releasing ${endpointHostname}`; - - beforeEach(() => { - login(); + let isolateComment: string; + let releaseComment: string; + let indexedPolicy: IndexedFleetEndpointPolicyResponse; + let policy: PolicyData; + let createdHost: CreateAndEnrollEndpointHostResponse; + + before(() => { + getEndpointIntegrationVersion().then((version) => { + createAgentPolicyTask(version).then((data) => { + indexedPolicy = data; + policy = indexedPolicy.integrationPolicies[0]; + + return enableAllPolicyProtections(policy.id).then(() => { + // Create and enroll a new Endpoint host + return createEndpointHost(policy.policy_id).then((host) => { + createdHost = host as CreateAndEnrollEndpointHostResponse; + isolateComment = `Isolating ${host.hostname}`; + releaseComment = `Releasing ${host.hostname}`; + }); + }); + }); + }); }); - describe('From manage', () => { - let response: IndexedFleetEndpointPolicyResponse; - let initialAgentData: Agent; + after(() => { + if (createdHost) { + cy.task('destroyEndpointHost', createdHost); + } - before(() => { - getAgentByHostName(endpointHostname).then((agentData) => { - initialAgentData = agentData; - }); + if (indexedPolicy) { + cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy); + } - getEndpointIntegrationVersion().then((version) => - createAgentPolicyTask(version).then((data) => { - response = data; - }) - ); - }); + if (createdHost) { + deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] }); + } + }); - after(() => { - if (initialAgentData?.policy_id) { - reassignAgentPolicy(initialAgentData.id, initialAgentData.policy_id); - } - if (response) { - cy.task('deleteIndexedFleetEndpointPolicies', response); - } - }); + beforeEach(() => { + login(); + }); + describe('From manage', () => { it('should allow filtering endpoint by Isolated status', () => { - cy.visit(APP_ENDPOINTS_PATH); + loadPage(APP_ENDPOINTS_PATH); closeAllToasts(); + cy.getByTestSubj('globalLoadingIndicator-hidden').should('exist'); checkEndpointListForOnlyUnIsolatedHosts(); filterOutIsolatedHosts(); @@ -79,11 +88,11 @@ describe('Isolate command', () => { cy.getByTestSubj('endpointTableRowActions').click(); cy.getByTestSubj('isolateLink').click(); - cy.contains(`Isolate host ${endpointHostname} from network.`); + cy.contains(`Isolate host ${createdHost.hostname} from network.`); cy.getByTestSubj('endpointHostIsolationForm'); cy.getByTestSubj('host_isolation_comment').type(isolateComment); cy.getByTestSubj('hostIsolateConfirmButton').click(); - cy.contains(`Isolation on host ${endpointHostname} successfully submitted`); + cy.contains(`Isolation on host ${createdHost.hostname} successfully submitted`); cy.getByTestSubj('euiFlyoutCloseButton').click(); cy.getByTestSubj('rowHostStatus-actionStatuses').should('contain.text', 'Isolated'); filterOutIsolatedHosts(); @@ -92,7 +101,7 @@ describe('Isolate command', () => { cy.getByTestSubj('endpointTableRowActions').click(); cy.getByTestSubj('unIsolateLink').click(); - releaseHostWithComment(releaseComment, endpointHostname); + releaseHostWithComment(releaseComment, createdHost.hostname); cy.contains('Confirm').click(); cy.getByTestSubj('euiFlyoutCloseButton').click(); cy.getByTestSubj('adminSearchBar').click().type('{selectall}{backspace}'); @@ -102,68 +111,49 @@ describe('Isolate command', () => { }); describe('From alerts', () => { - let response: IndexedFleetEndpointPolicyResponse; - let initialAgentData: Agent; let ruleId: string; let ruleName: string; before(() => { - getAgentByHostName(endpointHostname).then((agentData) => { - initialAgentData = agentData; - }); - - getEndpointIntegrationVersion().then((version) => - createAgentPolicyTask(version).then((data) => { - response = data; - }) - ); - loadRule(false).then((data) => { + loadRule( + { query: `agent.name: ${createdHost.hostname} and agent.type: endpoint` }, + false + ).then((data) => { ruleId = data.id; ruleName = data.name; }); }); after(() => { - if (initialAgentData?.policy_id) { - reassignAgentPolicy(initialAgentData.id, initialAgentData.policy_id); - } - if (response) { - cy.task('deleteIndexedFleetEndpointPolicies', response); - } if (ruleId) { cleanupRule(ruleId); } }); - it('should have generated endpoint and rule', () => { - cy.visit(APP_ENDPOINTS_PATH); - cy.contains(endpointHostname).should('exist'); + it('should isolate and release host', () => { + loadPage(APP_ENDPOINTS_PATH); + cy.contains(createdHost.hostname).should('exist'); toggleRuleOffAndOn(ruleName); - }); - - it('should isolate and release host', () => { visitRuleAlerts(ruleName); - filterOutEndpoints(endpointHostname); - closeAllToasts(); openAlertDetails(); - isolateHostWithComment(isolateComment, endpointHostname); + isolateHostWithComment(isolateComment, createdHost.hostname); cy.getByTestSubj('hostIsolateConfirmButton').click(); - cy.contains(`Isolation on host ${endpointHostname} successfully submitted`); + cy.contains(`Isolation on host ${createdHost.hostname} successfully submitted`); cy.getByTestSubj('euiFlyoutCloseButton').click(); openAlertDetails(); checkFlyoutEndpointIsolation(); - releaseHostWithComment(releaseComment, endpointHostname); + releaseHostWithComment(releaseComment, createdHost.hostname); cy.contains('Confirm').click(); - cy.contains(`Release on host ${endpointHostname} successfully submitted`); + cy.contains(`Release on host ${createdHost.hostname} successfully submitted`); cy.getByTestSubj('euiFlyoutCloseButton').click(); openAlertDetails(); cy.getByTestSubj('event-field-agent.status').within(() => { @@ -173,8 +163,6 @@ describe('Isolate command', () => { }); describe('From cases', () => { - let response: IndexedFleetEndpointPolicyResponse; - let initialAgentData: Agent; let ruleId: string; let ruleName: string; let caseId: string; @@ -182,16 +170,10 @@ describe('Isolate command', () => { const caseOwner = 'securitySolution'; before(() => { - getAgentByHostName(endpointHostname).then((agentData) => { - initialAgentData = agentData; - }); - getEndpointIntegrationVersion().then((version) => - createAgentPolicyTask(version).then((data) => { - response = data; - }) - ); - - loadRule(false).then((data) => { + loadRule( + { query: `agent.name: ${createdHost.hostname} and agent.type: endpoint` }, + false + ).then((data) => { ruleId = data.id; ruleName = data.name; }); @@ -205,12 +187,6 @@ describe('Isolate command', () => { }); after(() => { - if (initialAgentData?.policy_id) { - reassignAgentPolicy(initialAgentData.id, initialAgentData.policy_id); - } - if (response) { - cy.task('deleteIndexedFleetEndpointPolicies', response); - } if (ruleId) { cleanupRule(ruleId); } @@ -219,16 +195,13 @@ describe('Isolate command', () => { } }); - it('should have generated endpoint and rule', () => { - cy.visit(APP_ENDPOINTS_PATH); - cy.contains(endpointHostname).should('exist'); + it('should isolate and release host', () => { + loadPage(APP_ENDPOINTS_PATH); + cy.contains(createdHost.hostname).should('exist'); toggleRuleOffAndOn(ruleName); - }); - it('should isolate and release host', () => { visitRuleAlerts(ruleName); - filterOutEndpoints(endpointHostname); closeAllToasts(); openAlertDetails(); @@ -238,13 +211,13 @@ describe('Isolate command', () => { cy.contains(`An alert was added to \"Test ${caseOwner} case`); cy.intercept('GET', `/api/cases/${caseId}/user_actions/_find*`).as('case'); - cy.visit(`${APP_CASES_PATH}/${caseId}`); + loadPage(`${APP_CASES_PATH}/${caseId}`); cy.wait('@case', { timeout: 30000 }).then(({ response: res }) => { const caseAlertId = res?.body.userActions[1].id; closeAllToasts(); openCaseAlertDetails(caseAlertId); - isolateHostWithComment(isolateComment, endpointHostname); + isolateHostWithComment(isolateComment, createdHost.hostname); cy.getByTestSubj('hostIsolateConfirmButton').click(); cy.getByTestSubj('euiFlyoutCloseButton').click(); @@ -257,11 +230,11 @@ describe('Isolate command', () => { waitForReleaseOption(caseAlertId); - releaseHostWithComment(releaseComment, endpointHostname); + releaseHostWithComment(releaseComment, createdHost.hostname); cy.contains('Confirm').click(); - cy.contains(`Release on host ${endpointHostname} successfully submitted`); + cy.contains(`Release on host ${createdHost.hostname} successfully submitted`); cy.getByTestSubj('euiFlyoutCloseButton').click(); cy.getByTestSubj('user-actions-list').within(() => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/response_console.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/response_console.cy.ts index b8833ceb602c7..245de3ce5512c 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/response_console.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/endpoint/response_console.cy.ts @@ -23,14 +23,11 @@ import { } from '../../tasks/isolate'; import { login } from '../../tasks/login'; -import { ENDPOINT_VM_NAME } from '../../tasks/common'; import { enableAllPolicyProtections } from '../../tasks/endpoint_policy'; import { createEndpointHost } from '../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data'; describe('Response console', () => { - const endpointHostname = Cypress.env(ENDPOINT_VM_NAME); - beforeEach(() => { login(); }); @@ -58,7 +55,7 @@ describe('Response console', () => { after(() => { if (createdHost) { - cy.task('destroyEndpointHost', createdHost).then(() => {}); + cy.task('destroyEndpointHost', createdHost); } if (indexedPolicy) { @@ -72,25 +69,25 @@ describe('Response console', () => { it('should isolate host from response console', () => { const command = 'isolate'; - waitForEndpointListPageToBeLoaded(endpointHostname); + waitForEndpointListPageToBeLoaded(createdHost.hostname); checkEndpointListForOnlyUnIsolatedHosts(); openResponseConsoleFromEndpointList(); performCommandInputChecks(command); submitCommand(); waitForCommandToBeExecuted(command); - waitForEndpointListPageToBeLoaded(endpointHostname); + waitForEndpointListPageToBeLoaded(createdHost.hostname); checkEndpointListForOnlyIsolatedHosts(); }); it('should release host from response console', () => { const command = 'release'; - waitForEndpointListPageToBeLoaded(endpointHostname); + waitForEndpointListPageToBeLoaded(createdHost.hostname); checkEndpointListForOnlyIsolatedHosts(); openResponseConsoleFromEndpointList(); performCommandInputChecks(command); submitCommand(); waitForCommandToBeExecuted(command); - waitForEndpointListPageToBeLoaded(endpointHostname); + waitForEndpointListPageToBeLoaded(createdHost.hostname); checkEndpointListForOnlyUnIsolatedHosts(); }); }); @@ -121,7 +118,7 @@ describe('Response console', () => { after(() => { if (createdHost) { - cy.task('destroyEndpointHost', createdHost).then(() => {}); + cy.task('destroyEndpointHost', createdHost); } if (indexedPolicy) { @@ -134,7 +131,7 @@ describe('Response console', () => { }); it('"processes" - should obtain a list of processes', () => { - waitForEndpointListPageToBeLoaded(endpointHostname); + waitForEndpointListPageToBeLoaded(createdHost.hostname); openResponseConsoleFromEndpointList(); performCommandInputChecks('processes'); submitCommand(); @@ -159,7 +156,7 @@ describe('Response console', () => { }); it('"kill-process --pid" - should kill a process', () => { - waitForEndpointListPageToBeLoaded(endpointHostname); + waitForEndpointListPageToBeLoaded(createdHost.hostname); openResponseConsoleFromEndpointList(); inputConsoleCommand(`kill-process --pid ${cronPID}`); submitCommand(); @@ -183,7 +180,7 @@ describe('Response console', () => { }); it('"suspend-process --pid" - should suspend a process', () => { - waitForEndpointListPageToBeLoaded(endpointHostname); + waitForEndpointListPageToBeLoaded(createdHost.hostname); openResponseConsoleFromEndpointList(); inputConsoleCommand(`suspend-process --pid ${newCronPID}`); submitCommand(); @@ -191,11 +188,11 @@ describe('Response console', () => { }); }); - describe('File operations: get-file and execute', () => { - const homeFilePath = `/home/ubuntu`; + describe('File operations: get-file and execute', () => { + const homeFilePath = process.env.CI || true ? '/home/vagrant' : `/home/ubuntu`; const fileContent = 'This is a test file for the get-file command.'; - const filePath = `/home/ubuntu/test_file.txt`; + const filePath = `${homeFilePath}/test_file.txt`; let indexedPolicy: IndexedFleetEndpointPolicyResponse; let policy: PolicyData; @@ -219,7 +216,7 @@ describe('Response console', () => { after(() => { if (createdHost) { - cy.task('destroyEndpointHost', createdHost).then(() => {}); + cy.task('destroyEndpointHost', createdHost); } if (indexedPolicy) { @@ -232,7 +229,12 @@ describe('Response console', () => { }); it('"get-file --path" - should retrieve a file', () => { - waitForEndpointListPageToBeLoaded(endpointHostname); + waitForEndpointListPageToBeLoaded(createdHost.hostname); + cy.task('createFileOnEndpoint', { + hostname: createdHost.hostname, + path: filePath, + content: fileContent, + }); openResponseConsoleFromEndpointList(); inputConsoleCommand(`get-file --path ${filePath}`); submitCommand(); @@ -247,14 +249,14 @@ describe('Response console', () => { cy.readFile(`${downloadsFolder}/upload.zip`); cy.task('uploadFileToEndpoint', { - hostname: endpointHostname, + hostname: createdHost.hostname, srcPath: `${downloadsFolder}/upload.zip`, - destPath: '/home/ubuntu/upload.zip', + destPath: `${homeFilePath}/upload.zip`, }); cy.task('readZippedFileContentOnEndpoint', { - hostname: endpointHostname, - path: '/home/ubuntu/upload.zip', + hostname: createdHost.hostname, + path: `${homeFilePath}/upload.zip`, password: 'elastic', }).then((unzippedFileContent) => { expect(unzippedFileContent).to.equal(fileContent); @@ -262,8 +264,8 @@ describe('Response console', () => { }); }); - it('"execute --command" - should execute a command', async () => { - waitForEndpointListPageToBeLoaded(endpointHostname); + it('"execute --command" - should execute a command', () => { + waitForEndpointListPageToBeLoaded(createdHost.hostname); openResponseConsoleFromEndpointList(); inputConsoleCommand(`execute --command "ls -al ${homeFilePath}"`); submitCommand(); @@ -294,7 +296,7 @@ describe('Response console', () => { after(() => { if (createdHost) { - cy.task('destroyEndpointHost', createdHost).then(() => {}); + cy.task('destroyEndpointHost', createdHost); } if (indexedPolicy) { @@ -307,19 +309,19 @@ describe('Response console', () => { }); it('should fail if data tampered', () => { - waitForEndpointListPageToBeLoaded(endpointHostname); + waitForEndpointListPageToBeLoaded(createdHost.hostname); checkEndpointListForOnlyUnIsolatedHosts(); openResponseConsoleFromEndpointList(); performCommandInputChecks('isolate'); // stop host so that we ensure tamper happens before endpoint processes the action - cy.task('stopEndpointHost'); + cy.task('stopEndpointHost', createdHost.hostname); // get action doc before we submit command so we know when the new action doc is indexed cy.task('getLatestActionDoc').then((previousActionDoc) => { submitCommand(); cy.task('tamperActionDoc', previousActionDoc); }); - cy.task('startEndpointHost'); + cy.task('startEndpointHost', createdHost.hostname); const actionValidationErrorMsg = 'Fleet action response error: Failed to validate action signature; check Endpoint logs for details'; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/artifacts.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/artifacts.cy.ts index 0e468af132aae..53693ab40b651 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/artifacts.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/artifacts.cy.ts @@ -12,6 +12,7 @@ import { loginWithRole, ROLE, } from '../../tasks/login'; +import { loadPage } from '../../tasks/common'; import { getArtifactsListTestsData } from '../../fixtures/artifacts_page'; import { removeAllArtifacts } from '../../tasks/artifacts'; @@ -20,18 +21,18 @@ import { loadEndpointDataForEventFiltersIfNeeded } from '../../tasks/load_endpoi const loginWithWriteAccess = (url: string) => { loginWithRole(ROLE.endpoint_security_policy_manager); - cy.visit(url); + loadPage(url); }; const loginWithReadAccess = (privilegePrefix: string, url: string) => { const roleWithArtifactReadPrivilege = getRoleWithArtifactReadPrivilege(privilegePrefix); loginWithCustomRole('roleWithArtifactReadPrivilege', roleWithArtifactReadPrivilege); - cy.visit(url); + loadPage(url); }; const loginWithoutAccess = (url: string) => { loginWithRole(ROLE.t1_analyst); - cy.visit(url); + loadPage(url); }; describe('Artifacts pages', () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/endpoint_role_rbac.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/endpoint_role_rbac.cy.ts index 9493d779f3226..a3198d894076e 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/endpoint_role_rbac.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/endpoint_role_rbac.cy.ts @@ -7,6 +7,7 @@ import { closeAllToasts } from '../../tasks/toasts'; import { login } from '../../tasks/login'; +import { loadPage } from '../../tasks/common'; describe('When defining a kibana role for Endpoint security access', () => { const getAllSubFeatureRows = (): Cypress.Chainable> => { @@ -18,7 +19,7 @@ describe('When defining a kibana role for Endpoint security access', () => { beforeEach(() => { login(); - cy.visit('/app/management/security/roles/edit'); + loadPage('/app/management/security/roles/edit'); closeAllToasts(); cy.getByTestSubj('addSpacePrivilegeButton').click(); cy.getByTestSubj('featureCategoryButton_securitySolution').closest('button').click(); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/endpoints.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/endpoints.cy.ts index d5c946af96c14..6dd4b6664d6a3 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/endpoints.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/endpoints.cy.ts @@ -5,9 +5,11 @@ * 2.0. */ +import { APP_ENDPOINTS_PATH } from '../../../../../common/constants'; import type { ReturnTypeFromChainable } from '../../types'; import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts'; import { login } from '../../tasks/login'; +import { loadPage } from '../../tasks/common'; describe('Endpoints page', () => { let endpointData: ReturnTypeFromChainable; @@ -31,7 +33,7 @@ describe('Endpoints page', () => { }); it('Loads the endpoints page', () => { - cy.visit('/app/security/administration/endpoints'); + loadPage(APP_ENDPOINTS_PATH); cy.contains('Hosts running Elastic Defend').should('exist'); }); }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/isolate.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/isolate.cy.ts index 118eadd4fcd5b..f633fd25abdcc 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/isolate.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/isolate.cy.ts @@ -24,6 +24,7 @@ import type { ReturnTypeFromChainable } from '../../types'; import { addAlertsToCase } from '../../tasks/add_alerts_to_case'; import { APP_ALERTS_PATH, APP_CASES_PATH, APP_PATH } from '../../../../../common/constants'; import { login } from '../../tasks/login'; +import { loadPage } from '../../tasks/common'; import { indexNewCase } from '../../tasks/index_new_case'; import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts'; import { indexEndpointRuleAlerts } from '../../tasks/index_endpoint_rule_alerts'; @@ -78,7 +79,7 @@ describe('Isolate command', () => { }); it('should allow filtering endpoint by Isolated status', () => { - cy.visit(APP_PATH + getEndpointListPath({ name: 'endpointList' })); + loadPage(APP_PATH + getEndpointListPath({ name: 'endpointList' })); closeAllToasts(); filterOutIsolatedHosts(); isolatedEndpointHostnames.forEach(checkEndpointIsIsolated); @@ -130,7 +131,7 @@ describe('Isolate command', () => { let isolateRequestResponse: ActionDetails; let releaseRequestResponse: ActionDetails; - cy.visit(APP_ALERTS_PATH); + loadPage(APP_ALERTS_PATH); closeAllToasts(); cy.getByTestSubj('alertsTable').within(() => { @@ -256,7 +257,7 @@ describe('Isolate command', () => { const releaseComment = `Releasing ${hostname}`; const caseAlertId = caseAlertActions.comments[alertId]; - cy.visit(caseUrlPath); + loadPage(caseUrlPath); closeAllToasts(); openCaseAlertDetails(caseAlertId); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts index b829e6e21c585..741164cc6d433 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts @@ -8,6 +8,7 @@ import type { ReturnTypeFromChainable } from '../../types'; import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts'; import { login } from '../../tasks/login'; +import { loadPage } from '../../tasks/common'; describe('Response actions history page', () => { let endpointData: ReturnTypeFromChainable; @@ -33,7 +34,7 @@ describe('Response actions history page', () => { // Flakey, example build failure: https://buildkite.com/elastic/kibana-pull-request/builds/132245 it.skip('retains expanded action details on page reload', () => { - cy.visit(`/app/security/administration/response_actions_history`); + loadPage(`/app/security/administration/response_actions_history`); cy.getByTestSubj('response-actions-list-expand-button').eq(3).click(); // 4th row on 1st page cy.getByTestSubj('response-actions-list-details-tray').should('exist'); cy.url().should('include', 'withOutputs'); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/responder.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/responder.cy.ts index 881d1ec449eec..60775450c35e0 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/responder.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/responder.cy.ts @@ -16,6 +16,7 @@ import { setResponderActionLogDateRange, } from '../../screens/responder'; import { login } from '../../tasks/login'; +import { loadPage } from '../../tasks/common'; import { indexNewCase } from '../../tasks/index_new_case'; import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts'; import { indexEndpointRuleAlerts } from '../../tasks/index_endpoint_rule_alerts'; @@ -102,14 +103,14 @@ describe('When accessing Endpoint Response Console', () => { }); it('should display responder option in take action menu', () => { - cy.visit(caseUrlPath); + loadPage(caseUrlPath); closeAllToasts(); openCaseAlertDetails(); cy.getByTestSubj('endpointResponseActions-action-item').should('be.enabled'); }); it('should display Responder response action interface', () => { - cy.visit(caseUrlPath); + loadPage(caseUrlPath); closeAllToasts(); openCaseAlertDetails(); cy.getByTestSubj('endpointResponseActions-action-item').click(); diff --git a/x-pack/plugins/security_solution/public/management/cypress/screens/alerts.ts b/x-pack/plugins/security_solution/public/management/cypress/screens/alerts.ts index 48f0747464bf8..d9077bfb984a9 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/screens/alerts.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/screens/alerts.ts @@ -6,9 +6,10 @@ */ import { APP_ALERTS_PATH } from '../../../../common/constants'; +import { loadPage } from '../tasks/common'; export const navigateToAlertsList = (urlQueryParams: string = '') => { - cy.visit(`${APP_ALERTS_PATH}${urlQueryParams ? `?${urlQueryParams}` : ''}`); + loadPage(`${APP_ALERTS_PATH}${urlQueryParams ? `?${urlQueryParams}` : ''}`); }; export const clickAlertListRefreshButton = (): Cypress.Chainable => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/screens/endpoints.ts b/x-pack/plugins/security_solution/public/management/cypress/screens/endpoints.ts index da2c278b8e30d..ef5f7926e94dd 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/screens/endpoints.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/screens/endpoints.ts @@ -6,22 +6,17 @@ */ import { APP_PATH } from '../../../../common/constants'; -import { getEndpointDetailsPath, getEndpointListPath } from '../../common/routing'; +import { getEndpointDetailsPath } from '../../common/routing'; +import { loadPage } from '../tasks/common'; export const AGENT_HOSTNAME_CELL = 'hostnameCellLink'; export const AGENT_POLICY_CELL = 'policyNameCellLink'; export const TABLE_ROW_ACTIONS = 'endpointTableRowActions'; export const TABLE_ROW_ACTIONS_MENU = 'tableRowActionsMenuPanel'; -export const navigateToEndpointPolicyResponse = ( - endpointAgentId: string -): Cypress.Chainable => { - return cy.visit( +export const navigateToEndpointPolicyResponse = (endpointAgentId: string): void => { + loadPage( APP_PATH + getEndpointDetailsPath({ name: 'endpointPolicyResponse', selected_endpoint: endpointAgentId }) ); }; - -export const navigateToEndpointList = (): Cypress.Chainable => { - return cy.visit(APP_PATH + getEndpointListPath({ name: 'endpointList' })); -}; diff --git a/x-pack/plugins/security_solution/public/management/cypress/screens/fleet.ts b/x-pack/plugins/security_solution/public/management/cypress/screens/fleet.ts index 0269779d41bf1..f1bf244c7558c 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/screens/fleet.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/screens/fleet.ts @@ -6,18 +6,15 @@ */ import { FLEET_BASE_PATH } from '@kbn/fleet-plugin/public/constants'; +import { loadPage } from '../tasks/common'; export const FLEET_REASSIGN_POLICY_MODAL = 'agentReassignPolicyModal'; export const FLEET_REASSIGN_POLICY_MODAL_CONFIRM_BUTTON = 'confirmModalConfirmButton'; -export const navigateToFleetAgentDetails = ( - agentId: string -): Cypress.Chainable => { +export const navigateToFleetAgentDetails = (agentId: string): void => { // FYI: attempted to use fleet's `pagePathGetters()`, but got compile // errors due to it pulling too many modules - const response = cy.visit(`${FLEET_BASE_PATH}/agents/${agentId}`); + loadPage(`${FLEET_BASE_PATH}/agents/${agentId}`); cy.getByTestSubj('agentPolicyNameLink').should('be.visible'); - - return response; }; diff --git a/x-pack/plugins/security_solution/public/management/cypress/screens/policy_details.ts b/x-pack/plugins/security_solution/public/management/cypress/screens/policy_details.ts index f9b84d4cc6e3a..de4649d3bab4c 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/screens/policy_details.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/screens/policy_details.ts @@ -15,11 +15,11 @@ import type { import { packagePolicyRouteService } from '@kbn/fleet-plugin/common'; import { APP_POLICIES_PATH } from '../../../../common/constants'; import type { PolicyConfig } from '../../../../common/endpoint/types'; -import { request } from '../tasks/common'; +import { request, loadPage } from '../tasks/common'; import { expectAndCloseSuccessToast } from '../tasks/toasts'; export const visitPolicyDetailsPage = () => { - cy.visit(APP_POLICIES_PATH); + loadPage(APP_POLICIES_PATH); cy.getByTestSubj('policyNameCellLink').eq(0).click({ force: true }); cy.getByTestSubj('policyDetailsPage').should('exist'); diff --git a/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts b/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts index 32ada46f13127..f54c780ab5113 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts @@ -9,6 +9,8 @@ import type { CasePostRequest } from '@kbn/cases-plugin/common/api'; import execa from 'execa'; +import { startRuntimeServices } from '../../../../scripts/endpoint/endpoint_agent_runner/runtime'; +import { runFleetServerIfNeeded } from '../../../../scripts/endpoint/endpoint_agent_runner/fleet_server'; import { sendEndpointActionResponse, sendFleetActionResponse, @@ -50,8 +52,8 @@ import { startEndpointHost, createAndEnrollEndpointHost, destroyEndpointHost, - getEndpointHosts, stopEndpointHost, + VAGRANT_CWD, } from '../../../../scripts/endpoint/common/endpoint_host_services'; /** @@ -204,6 +206,8 @@ export const dataLoadersForRealEndpoints = ( on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions ): void => { + let fleetServerContainerId: string | undefined; + const stackServicesPromise = createRuntimeServices({ kibanaUrl: config.env.KIBANA_URL, elasticsearchUrl: config.env.ELASTICSEARCH_URL, @@ -213,6 +217,25 @@ export const dataLoadersForRealEndpoints = ( asSuperuser: true, }); + on('before:run', async () => { + await startRuntimeServices({ + kibanaUrl: config.env.KIBANA_URL, + elasticUrl: config.env.ELASTICSEARCH_URL, + fleetServerUrl: config.env.FLEET_SERVER_URL, + username: config.env.ELASTICSEARCH_USERNAME, + password: config.env.ELASTICSEARCH_PASSWORD, + asSuperuser: true, + }); + const data = await runFleetServerIfNeeded(); + fleetServerContainerId = data?.fleetServerContainerId; + }); + + on('after:run', () => { + if (fleetServerContainerId) { + execa.sync('docker', ['kill', fleetServerContainerId]); + } + }); + on('task', { createEndpointHost: async ( options: Omit @@ -224,7 +247,7 @@ export const dataLoadersForRealEndpoints = ( log, kbnClient, }).then((newHost) => { - return waitForEndpointToStreamData(kbnClient, newHost.agentId, 120000).then(() => { + return waitForEndpointToStreamData(kbnClient, newHost.agentId, 360000).then(() => { return newHost; }); }); @@ -246,7 +269,15 @@ export const dataLoadersForRealEndpoints = ( path: string; content: string; }): Promise => { - await execa(`multipass`, ['exec', hostname, '--', 'sh', '-c', `echo ${content} > ${path}`]); + if (process.env.CI) { + await execa('vagrant', ['ssh', '--', `echo ${content} > ${path}`], { + env: { + VAGRANT_CWD, + }, + }); + } else { + await execa(`multipass`, ['exec', hostname, '--', 'sh', '-c', `echo ${content} > ${path}`]); + } return null; }, @@ -259,7 +290,16 @@ export const dataLoadersForRealEndpoints = ( srcPath: string; destPath: string; }): Promise => { - await execa(`multipass`, ['transfer', srcPath, `${hostname}:${destPath}`]); + if (process.env.CI) { + await execa('vagrant', ['upload', srcPath, destPath], { + env: { + VAGRANT_CWD, + }, + }); + } else { + await execa(`multipass`, ['transfer', srcPath, `${hostname}:${destPath}`]); + } + return null; }, @@ -290,26 +330,37 @@ export const dataLoadersForRealEndpoints = ( path: string; password?: string; }): Promise => { - const result = await execa(`multipass`, [ - 'exec', - hostname, - '--', - 'sh', - '-c', - `unzip -p ${password ? `-P ${password} ` : ''}${path}`, - ]); + let result; + + if (process.env.CI) { + result = await execa( + `vagrant`, + ['ssh', '--', `unzip -p ${password ? `-P ${password} ` : ''}${path}`], + { + env: { + VAGRANT_CWD, + }, + } + ); + } else { + result = await execa(`multipass`, [ + 'exec', + hostname, + '--', + 'sh', + '-c', + `unzip -p ${password ? `-P ${password} ` : ''}${path}`, + ]); + } + return result.stdout; }, - stopEndpointHost: async () => { - const hosts = await getEndpointHosts(); - const hostName = hosts[0].name; + stopEndpointHost: async (hostName) => { return stopEndpointHost(hostName); }, - startEndpointHost: async () => { - const hosts = await getEndpointHosts(); - const hostName = hosts[0].name; + startEndpointHost: async (hostName) => { return startEndpointHost(hostName); }, }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/api_fixtures.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/api_fixtures.ts index 708c10ac3cc4d..f574de69cef7b 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/api_fixtures.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/api_fixtures.ts @@ -16,7 +16,7 @@ export const cleanupRule = (id: string) => { request({ method: 'DELETE', url: `/api/detection_engine/rules?id=${id}` }); }; -export const loadRule = (includeResponseActions = true) => +export const loadRule = (body = {}, includeResponseActions = true) => request({ method: 'POST', url: `/api/detection_engine/rules`, @@ -55,6 +55,7 @@ export const loadRule = (includeResponseActions = true) => actions: [], enabled: true, throttle: 'no_actions', + ...body, ...(includeResponseActions ? { response_actions: [ diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/common.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/common.ts index 498eb656dd5be..7a6c964e0a225 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/common.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/common.ts @@ -5,20 +5,29 @@ * 2.0. */ -export const ENDPOINT_VM_NAME = 'ENDPOINT_VM_NAME'; - export const API_AUTH = Object.freeze({ user: Cypress.env('ELASTICSEARCH_USERNAME'), pass: Cypress.env('ELASTICSEARCH_PASSWORD'), }); -export const API_HEADERS = Object.freeze({ 'kbn-xsrf': 'cypress' }); +export const COMMON_API_HEADERS = { 'kbn-xsrf': 'cypress' }; + +export const waitForPageToBeLoaded = () => { + cy.getByTestSubj('globalLoadingIndicator-hidden').should('exist'); + cy.getByTestSubj('globalLoadingIndicator').should('not.exist'); +}; + +export const loadPage = (url: string, options: Partial = {}) => { + cy.visit(url, options); + waitForPageToBeLoaded(); +}; -export const request = ( - options: Partial -): Cypress.Chainable> => +export const request = ({ + headers, + ...options +}: Partial): Cypress.Chainable> => cy.request({ auth: API_AUTH, - headers: API_HEADERS, + headers: Object.freeze({ ...COMMON_API_HEADERS, ...headers }), ...options, }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/create_endpoint_host.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/create_endpoint_host.ts index 6a5027655f391..cac8c284acdbd 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/create_endpoint_host.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/create_endpoint_host.ts @@ -17,6 +17,6 @@ export const createEndpointHost = ( { agentPolicyId, }, - { timeout: timeout ?? 180000 } + { timeout: timeout ?? 600000 } ); }; diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/isolate.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/isolate.ts index 0b0303434e52a..2c76247b24780 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/isolate.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/isolate.ts @@ -6,6 +6,7 @@ */ import type { ActionDetails } from '../../../../common/endpoint/types'; +import { loadPage } from './common'; const API_ENDPOINT_ACTION_PATH = '/api/endpoint/action/*'; export const interceptActionRequests = ( @@ -70,9 +71,10 @@ export const waitForReleaseOption = (alertId: string): void => { }; export const visitRuleAlerts = (ruleName: string) => { - cy.visit('/app/security/rules'); + loadPage('/app/security/rules'); cy.contains(ruleName).click(); }; + export const checkFlyoutEndpointIsolation = (): void => { cy.getByTestSubj('event-field-agent.status').then(($status) => { if ($status.find('[title="Isolated"]').length > 0) { @@ -90,7 +92,7 @@ export const checkFlyoutEndpointIsolation = (): void => { }; export const toggleRuleOffAndOn = (ruleName: string): void => { - cy.visit('/app/security/rules'); + loadPage('/app/security/rules'); cy.wait(2000); cy.contains(ruleName) .parents('tr') @@ -105,7 +107,8 @@ export const toggleRuleOffAndOn = (ruleName: string): void => { export const filterOutEndpoints = (endpointHostname: string): void => { cy.getByTestSubj('filters-global-container').within(() => { - cy.getByTestSubj('queryInput').click().type(`host.hostname : "${endpointHostname}"`); + cy.getByTestSubj('queryInput').click(); + cy.getByTestSubj('queryInput').type(`host.name: ${endpointHostname}`); cy.getByTestSubj('querySubmitButton').click(); }); }; diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/login.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/login.ts index 2dfed4e116956..4cea17dfd6432 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/login.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/login.ts @@ -13,7 +13,7 @@ import Url from 'url'; import type { Role } from '@kbn/security-plugin/common'; import { getWithResponseActionsRole } from '../../../../scripts/endpoint/common/roles_users/with_response_actions_role'; import { getNoResponseActionsRole } from '../../../../scripts/endpoint/common/roles_users/without_response_actions_role'; -import { request } from './common'; +import { request, loadPage } from './common'; import { getT1Analyst } from '../../../../scripts/endpoint/common/roles_users/t1_analyst'; import { getT2Analyst } from '../../../../scripts/endpoint/common/roles_users/t2_analyst'; import { getHunter } from '../../../../scripts/endpoint/common/roles_users/hunter'; @@ -342,7 +342,7 @@ export const getEnvAuth = (): User => { */ export const loginAndWaitForPage = (url: string) => { login(); - cy.visit(url); + loadPage(url); }; export const getRoleWithArtifactReadPrivilege = (privilegePrefix: string) => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/navigation.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/navigation.ts index 9052004b66f0e..5dea2652a3947 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/navigation.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/navigation.ts @@ -6,12 +6,13 @@ */ import { TOGGLE_NAVIGATION_BTN } from '../screens/navigation'; +import { loadPage } from './common'; export const INTEGRATIONS = 'app/integrations#/'; export const FLEET = 'app/fleet/'; export const FLEET_AGENT_POLICIES = 'app/fleet/policies'; export const navigateTo = (page: string, opts?: Partial) => { - cy.visit(page, opts); + loadPage(page, opts); cy.contains('Loading Elastic').should('exist'); cy.contains('Loading Elastic').should('not.exist'); diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts index 72c795967ea0e..911f8a0511c11 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { request } from './common'; +import { request, loadPage } from './common'; import { resolvePathVariables } from '../../../common/utils/resolve_path_variables'; import { ACTION_DETAILS_ROUTE } from '../../../../common/endpoint/constants'; import type { ActionDetails, ActionDetailsApiResponse } from '../../../../common/endpoint/types'; @@ -32,7 +32,7 @@ export const focusAndOpenCommandDropdown = (number = 0) => { }); }; export const fillUpNewRule = (name = 'Test', description = 'Test') => { - cy.visit('app/security/rules/management'); + loadPage('app/security/rules/management'); cy.getByTestSubj('create-new-rule').click(); cy.getByTestSubj('stepDefineRule').within(() => { cy.getByTestSubj('queryInput').first().type('_id:*{enter}'); @@ -48,7 +48,7 @@ export const fillUpNewRule = (name = 'Test', description = 'Test') => { cy.getByTestSubj('schedule-continue').click(); }; export const visitRuleActions = (ruleId: string) => { - cy.visit(`app/security/rules/id/${ruleId}/edit`); + loadPage(`app/security/rules/id/${ruleId}/edit`); cy.getByTestSubj('edit-rule-actions-tab').should('exist'); cy.getByTestSubj('globalLoadingIndicator').should('not.exist'); cy.getByTestSubj('stepPanelProgress').should('not.exist'); @@ -74,7 +74,7 @@ export const tryAddingDisabledResponseAction = (itemNumber = 0) => { */ export const waitForActionToComplete = ( actionId: string, - timeout = 60000 + timeout = 120000 ): Cypress.Chainable => { let action: ActionDetails | undefined; diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/response_console.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/response_console.ts index 54ec6c08009f9..19ef3c5d68d37 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/response_console.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/response_console.ts @@ -8,10 +8,11 @@ import type { ConsoleResponseActionCommands } from '../../../../common/endpoint/service/response_actions/constants'; import { closeAllToasts } from './toasts'; import { APP_ENDPOINTS_PATH } from '../../../../common/constants'; +import { loadPage } from './common'; import Chainable = Cypress.Chainable; export const waitForEndpointListPageToBeLoaded = (endpointHostname: string): void => { - cy.visit(APP_ENDPOINTS_PATH); + loadPage(APP_ENDPOINTS_PATH); closeAllToasts(); cy.contains(endpointHostname).should('exist'); }; diff --git a/x-pack/plugins/security_solution/public/management/cypress_endpoint.config.ts b/x-pack/plugins/security_solution/public/management/cypress_endpoint.config.ts index c707453ec4c99..36f68e73e6bcd 100644 --- a/x-pack/plugins/security_solution/public/management/cypress_endpoint.config.ts +++ b/x-pack/plugins/security_solution/public/management/cypress_endpoint.config.ts @@ -37,6 +37,8 @@ export default defineCypressConfig({ }, e2e: { + experimentalMemoryManagement: true, + experimentalInteractiveRunEvents: true, baseUrl: 'http://localhost:5620', supportFile: 'public/management/cypress/support/e2e.ts', specPattern: 'public/management/cypress/e2e/endpoint/*.cy.{js,jsx,ts,tsx}', diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/endpoint_host_services.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/endpoint_host_services.ts index 6add9eb06a39b..8c4bdac30362e 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/endpoint_host_services.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/endpoint_host_services.ts @@ -20,6 +20,8 @@ import { waitForHostToEnroll, } from './fleet_services'; +export const VAGRANT_CWD = `${__dirname}/../endpoint_agent_runner/`; + export interface CreateAndEnrollEndpointHostOptions extends Pick { kbnClient: KbnClient; @@ -60,38 +62,48 @@ export const createAndEnrollEndpointHost = async ({ deleted: [], }); - const [vm, agentDownload, fleetServerUrl, enrollmentToken] = await Promise.all([ - createMultipassVm({ - vmName: hostname ?? `test-host-${Math.random().toString().substring(2, 6)}`, - disk, - cpus, - memory, - }), - - getAgentDownloadUrl(version, useClosestVersionMatch, log).then<{ - url: string; - cache?: DownloadedAgentInfo; - }>((url) => { - if (useCache) { - cacheCleanupPromise = cleanupDownloads(); - - return downloadAndStoreAgent(url).then((cache) => { - return { - url, - cache, - }; - }); - } - - return { url }; - }), + const vmName = hostname ?? `test-host-${Math.random().toString().substring(2, 6)}`; + + const agentDownload = await getAgentDownloadUrl(version, useClosestVersionMatch, log).then<{ + url: string; + cache?: DownloadedAgentInfo; + }>((url) => { + if (useCache) { + cacheCleanupPromise = cleanupDownloads(); + + return downloadAndStoreAgent(url).then((cache) => { + return { + url, + cache, + }; + }); + } + + return { url }; + }); + + const [vm, fleetServerUrl, enrollmentToken] = await Promise.all([ + process.env.CI + ? createVagrantVm({ + vmName, + log, + cachedAgentDownload: agentDownload.cache as DownloadedAgentInfo, + }) + : createMultipassVm({ + vmName, + disk, + cpus, + memory, + }), fetchFleetServerUrl(kbnClient), fetchAgentPolicyEnrollmentKey(kbnClient, agentPolicyId), ]); - log.verbose(await execa('multipass', ['info', vm.vmName])); + if (!process.env.CI) { + log.verbose(await execa('multipass', ['info', vm.vmName])); + } // Some validations before we proceed assert(agentDownload.url, 'Missing agent download URL'); @@ -143,6 +155,54 @@ export const destroyEndpointHost = async ( ]); }; +interface CreateVmResponse { + vmName: string; +} + +interface CreateVagrantVmOptions { + vmName: string; + cachedAgentDownload: DownloadedAgentInfo; + log: ToolingLog; +} + +/** + * Creates a new VM using `vagrant` + */ +const createVagrantVm = async ({ + vmName, + cachedAgentDownload, + log, +}: CreateVagrantVmOptions): Promise => { + try { + await execa.command(`vagrant destroy -f`, { + env: { + VAGRANT_CWD, + }, + }); + // eslint-disable-next-line no-empty + } catch (e) {} + + try { + await execa.command(`vagrant up`, { + env: { + VAGRANT_DISABLE_VBOXSYMLINKCREATE: '1', + VAGRANT_CWD, + VMNAME: vmName, + CACHED_AGENT_SOURCE: cachedAgentDownload.fullFilePath, + CACHED_AGENT_FILENAME: cachedAgentDownload.filename, + }, + stdio: ['inherit', 'inherit', 'inherit'], + }); + } catch (e) { + log.error(e); + throw e; + } + + return { + vmName, + }; +}; + interface CreateMultipassVmOptions { vmName: string; /** Number of CPUs */ @@ -153,10 +213,6 @@ interface CreateMultipassVmOptions { memory?: string; } -interface CreateMultipassVmResponse { - vmName: string; -} - /** * Creates a new VM using `multipass` */ @@ -165,7 +221,7 @@ const createMultipassVm = async ({ disk = '8G', cpus = 1, memory = '1G', -}: CreateMultipassVmOptions): Promise => { +}: CreateMultipassVmOptions): Promise => { await execa.command( `multipass launch --name ${vmName} --disk ${disk} --cpus ${cpus} --memory ${memory}` ); @@ -176,7 +232,15 @@ const createMultipassVm = async ({ }; const deleteMultipassVm = async (vmName: string): Promise => { - await execa.command(`multipass delete -p ${vmName}`); + if (process.env.CI) { + await execa.command(`vagrant destroy -f`, { + env: { + VAGRANT_CWD, + }, + }); + } else { + await execa.command(`multipass delete -p ${vmName}`); + } }; interface EnrollHostWithFleetOptions { @@ -206,35 +270,30 @@ const enrollHostWithFleet = async ({ `Installing agent on host using cached download from [${cachedAgentDownload.fullFilePath}]` ); - // mount local folder on VM - await execa.command( - `multipass mount ${cachedAgentDownload.directory} ${vmName}:~/_agent_downloads` - ); - await execa.command( - `multipass exec ${vmName} -- tar -zxf _agent_downloads/${cachedAgentDownload.filename}` - ); - await execa.command(`multipass unmount ${vmName}:~/_agent_downloads`); + if (!process.env.CI) { + // mount local folder on VM + await execa.command( + `multipass mount ${cachedAgentDownload.directory} ${vmName}:~/_agent_downloads` + ); + await execa.command( + `multipass exec ${vmName} -- tar -zxf _agent_downloads/${cachedAgentDownload.filename}` + ); + await execa.command(`multipass unmount ${vmName}:~/_agent_downloads`); + } } else { log.verbose(`downloading and installing agent from URL [${agentDownloadUrl}]`); - // download into VM - await execa.command( - `multipass exec ${vmName} -- curl -L ${agentDownloadUrl} -o ${agentDownloadedFile}` - ); - await execa.command(`multipass exec ${vmName} -- tar -zxf ${agentDownloadedFile}`); - await execa.command(`multipass exec ${vmName} -- rm -f ${agentDownloadedFile}`); + if (!process.env.CI) { + // download into VM + await execa.command( + `multipass exec ${vmName} -- curl -L ${agentDownloadUrl} -o ${agentDownloadedFile}` + ); + await execa.command(`multipass exec ${vmName} -- tar -zxf ${agentDownloadedFile}`); + await execa.command(`multipass exec ${vmName} -- rm -f ${agentDownloadedFile}`); + } } const agentInstallArguments = [ - 'exec', - - vmName, - - '--working-directory', - `/home/ubuntu/${vmDirName}`, - - '--', - 'sudo', './elastic-agent', @@ -253,10 +312,28 @@ const enrollHostWithFleet = async ({ ]; log.info(`Enrolling elastic agent with Fleet`); - log.verbose(`Command: multipass ${agentInstallArguments.join(' ')}`); + if (process.env.CI) { + log.verbose(`Command: vagrant ${agentInstallArguments.join(' ')}`); + + await execa(`vagrant`, ['ssh', '--', `cd ${vmDirName} && ${agentInstallArguments.join(' ')}`], { + env: { + VAGRANT_CWD, + }, + stdio: ['inherit', 'inherit', 'inherit'], + }); + } else { + log.verbose(`Command: multipass ${agentInstallArguments.join(' ')}`); - await execa(`multipass`, agentInstallArguments); + await execa(`multipass`, [ + 'exec', + vmName, + '--working-directory', + `/home/ubuntu/${vmDirName}`, + '--', + ...agentInstallArguments, + ]); + } log.info(`Waiting for Agent to check-in with Fleet`); const agent = await waitForHostToEnroll(kbnClient, vmName, 120000); @@ -273,9 +350,24 @@ export async function getEndpointHosts(): Promise< } export function stopEndpointHost(hostName: string) { + if (process.env.CI) { + return execa('vagrant', ['suspend'], { + env: { + VAGRANT_CWD, + VMNAME: hostName, + }, + }); + } return execa('multipass', ['stop', hostName]); } export function startEndpointHost(hostName: string) { + if (process.env.CI) { + return execa('vagrant', ['up'], { + env: { + VAGRANT_CWD, + }, + }); + } return execa('multipass', ['start', hostName]); } diff --git a/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/Vagrantfile b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/Vagrantfile new file mode 100644 index 0000000000000..42080eab2984e --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/Vagrantfile @@ -0,0 +1,29 @@ +hostname = ENV["VMNAME"] || 'ubuntu' +cachedAgentSource = ENV["CACHED_AGENT_SOURCE"] || '' +cachedAgentFilename = ENV["CACHED_AGENT_FILENAME"] || '' + +Vagrant.configure("2") do |config| + config.vm.hostname = hostname + config.vm.box = 'ubuntu/jammy64' + + config.vm.provider :virtualbox do |vb| + vb.memory = 4096 + vb.cpus = 2 + end + + config.vm.provider :vmware_desktop do |v, override| + override.vm.box = "starboard/ubuntu-arm64-20.04.5" + override.vm.box_version = "20221120.20.40.0" + override.vm.box_download_insecure = true + override.vm.network "private_network", type: "dhcp" + + v.ssh_info_public = true + v.gui = true + v.linked_clone = false + v.vmx["ethernet0.virtualdev"] = "vmxnet3" + end + + config.vm.provision "file", source: cachedAgentSource, destination: "~/#{cachedAgentFilename}" + config.vm.provision "shell", inline: "tar -zxf #{cachedAgentFilename} && rm -f #{cachedAgentFilename}" + config.vm.provision "shell", inline: "sudo apt-get install unzip" +end diff --git a/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/elastic_endpoint.ts b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/elastic_endpoint.ts index 0c53f84cb9965..dcab47a3e030e 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/elastic_endpoint.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/elastic_endpoint.ts @@ -60,13 +60,23 @@ export const enrollEndpointHost = async (): Promise => { disk: '8G', }); - log.info(`VM created using Multipass. - VM Name: ${vmName} - Elastic Agent Version: ${version} - - Shell access: ${chalk.bold(`multipass shell ${vmName}`)} - Delete VM: ${chalk.bold(`multipass delete -p ${vmName}${await getVmCountNotice()}`)} -`); + if (process.env.CI) { + log.info(`VM created using Vagrant. + VM Name: ${vmName} + Elastic Agent Version: ${version} + + Shell access: ${chalk.bold(`vagrant ssh ${vmName}`)} + Delete VM: ${chalk.bold(`vagrant destroy ${vmName} -f`)} + `); + } else { + log.info(`VM created using Multipass. + VM Name: ${vmName} + Elastic Agent Version: ${version} + + Shell access: ${chalk.bold(`multipass shell ${vmName}`)} + Delete VM: ${chalk.bold(`multipass delete -p ${vmName}${await getVmCountNotice()}`)} + `); + } } catch (error) { log.error(dump(error)); log.indent(-4); diff --git a/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/fleet_server.ts b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/fleet_server.ts index 49701f3c41fa7..c141ad1c3abd1 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/fleet_server.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/fleet_server.ts @@ -50,22 +50,11 @@ export const runFleetServerIfNeeded = async (): Promise< const { log, kibana: { isLocalhost: isKibanaOnLocalhost }, - kbnClient, } = getRuntimeServices(); log.info(`Setting up fleet server (if necessary)`); log.indent(4); - const currentFleetServerUrl = await fetchFleetServerUrl(kbnClient); - - if (currentFleetServerUrl) { - log.info( - `Fleet server is already enrolled with Fleet - URL:\n${currentFleetServerUrl}\nNothing to do.` - ); - log.indent(-4); - return; - } - try { fleetServerAgentPolicyId = await getOrCreateFleetServerAgentPolicyId(); const serviceToken = await generateFleetServiceToken(); diff --git a/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/runtime.ts b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/runtime.ts index d267c70be8a78..c7680a42bbbbe 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/runtime.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/runtime.ts @@ -37,6 +37,7 @@ export const startRuntimeServices = async ({ username, password, log, + asSuperuser: otherOptions?.asSuperuser, }); runtimeServices = { diff --git a/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/types.ts b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/types.ts index 7215fb311d77a..ac75d1f8f64e8 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/types.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/endpoint_agent_runner/types.ts @@ -16,4 +16,5 @@ export interface StartRuntimeServicesOptions { version?: string; policy?: string; log?: ToolingLog; + asSuperuser?: boolean; } diff --git a/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts b/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts index 3c14adff1ccc4..f18a36656ead8 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts @@ -99,6 +99,10 @@ export const cli = () => { }; const getKibanaPort = (): T | number => { + if (isOpen) { + return 5620; + } + const kibanaPort = parseInt(`56${Math.floor(Math.random() * 89) + 10}`, 10); if (kibanaPorts.includes(kibanaPort)) { return getKibanaPort(); @@ -108,6 +112,10 @@ export const cli = () => { }; const getFleetServerPort = (): T | number => { + if (isOpen) { + return 8220; + } + const fleetServerPort = parseInt(`82${Math.floor(Math.random() * 89) + 10}`, 10); if (fleetServerPorts.includes(fleetServerPort)) { return getFleetServerPort(); @@ -378,7 +386,7 @@ export const cli = () => { } await procs.stop('kibana'); - shutdownEs(); + await shutdownEs(); cleanupServerPorts({ esPort, kibanaPort, fleetServerPort }); return result; diff --git a/x-pack/test/defend_workflows_cypress/agent.ts b/x-pack/test/defend_workflows_cypress/agent.ts deleted file mode 100644 index 91bf42d8adcf6..0000000000000 --- a/x-pack/test/defend_workflows_cypress/agent.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import execa from 'execa'; -import { ToolingLog } from '@kbn/tooling-log'; -import { enrollEndpointHost } from '@kbn/security-solution-plugin/scripts/endpoint/endpoint_agent_runner/elastic_endpoint'; -import { Manager } from './resource_manager'; - -export class AgentManager extends Manager { - private log: ToolingLog; - private vmName?: string; - constructor(log: ToolingLog) { - super(); - this.log = log; - this.vmName = undefined; - } - - public async setup() { - this.vmName = await enrollEndpointHost(); - - return this.vmName; - } - - public cleanup() { - super.cleanup(); - this.log.info('Cleaning up the agent process'); - if (this.vmName) { - execa.commandSync(`multipass delete -p ${this.vmName}`); - - this.log.info('Agent process closed'); - } - } -} diff --git a/x-pack/test/defend_workflows_cypress/config.ts b/x-pack/test/defend_workflows_cypress/config.ts index ac066782ac087..35f54fb5b94e7 100644 --- a/x-pack/test/defend_workflows_cypress/config.ts +++ b/x-pack/test/defend_workflows_cypress/config.ts @@ -49,7 +49,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { 'servers.elasticsearch.port' )}`, `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'endpointRbacEnabled', 'endpointResponseActionsEnabled', ])}`, ], diff --git a/x-pack/test/defend_workflows_cypress/endpoint_config.ts b/x-pack/test/defend_workflows_cypress/endpoint_config.ts index a1e437a442a87..c2d9bb6909bd9 100644 --- a/x-pack/test/defend_workflows_cypress/endpoint_config.ts +++ b/x-pack/test/defend_workflows_cypress/endpoint_config.ts @@ -9,7 +9,7 @@ import { getLocalhostRealIp } from '@kbn/security-solution-plugin/scripts/endpoi import { FtrConfigProviderContext } from '@kbn/test'; import { ExperimentalFeatures } from '@kbn/security-solution-plugin/common/experimental_features'; -import { DefendWorkflowsCypressEndpointTestRunner } from './runner'; +import { DefendWorkflowsCypressCliTestRunner } from './runner'; export default async function ({ readConfigFile }: FtrConfigProviderContext) { const defendWorkflowsCypressConfig = await readConfigFile(require.resolve('./config.ts')); @@ -43,6 +43,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { `--xpack.securitySolution.enableExperimental=${JSON.stringify(enabledFeatureFlags)}`, ], }, - testRunner: DefendWorkflowsCypressEndpointTestRunner, + testRunner: DefendWorkflowsCypressCliTestRunner, }; } diff --git a/x-pack/test/defend_workflows_cypress/fleet_server.ts b/x-pack/test/defend_workflows_cypress/fleet_server.ts deleted file mode 100644 index 94e24606e84ed..0000000000000 --- a/x-pack/test/defend_workflows_cypress/fleet_server.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import execa from 'execa'; -import { ToolingLog } from '@kbn/tooling-log'; -import { runFleetServerIfNeeded } from '@kbn/security-solution-plugin/scripts/endpoint/endpoint_agent_runner/fleet_server'; -import { Manager } from './resource_manager'; - -export class FleetManager extends Manager { - private fleetContainerId?: string; - private log: ToolingLog; - - constructor(log: ToolingLog) { - super(); - this.log = log; - } - - public async setup(): Promise { - const fleetServerConfig = await runFleetServerIfNeeded(); - - if (!fleetServerConfig) { - throw new Error('Fleet server config not found'); - } - - this.fleetContainerId = fleetServerConfig.fleetServerContainerId; - } - - public cleanup() { - super.cleanup(); - - this.log.info('Removing old fleet config'); - if (this.fleetContainerId) { - this.log.info('Closing fleet process'); - - execa.sync('docker', ['kill', this.fleetContainerId]); - this.log.info('Fleet server process closed'); - } - } -} diff --git a/x-pack/test/defend_workflows_cypress/resource_manager.ts b/x-pack/test/defend_workflows_cypress/resource_manager.ts deleted file mode 100644 index 0c030ebfa9f56..0000000000000 --- a/x-pack/test/defend_workflows_cypress/resource_manager.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -const CLEANUP_EVENTS = ['SIGINT', 'exit', 'uncaughtException', 'unhandledRejection']; -export class Manager { - constructor() { - const cleanup = () => this.cleanup(); - CLEANUP_EVENTS.forEach((ev) => process.on(ev, cleanup)); - } - cleanup() {} -} diff --git a/x-pack/test/defend_workflows_cypress/runner.ts b/x-pack/test/defend_workflows_cypress/runner.ts index 90a1b1583aa09..1e6d6ca29d02a 100644 --- a/x-pack/test/defend_workflows_cypress/runner.ts +++ b/x-pack/test/defend_workflows_cypress/runner.ts @@ -6,72 +6,9 @@ */ import Url from 'url'; -import { startRuntimeServices } from '@kbn/security-solution-plugin/scripts/endpoint/endpoint_agent_runner/runtime'; import { FtrProviderContext } from './ftr_provider_context'; -import { AgentManager } from './agent'; -import { FleetManager } from './fleet_server'; -import { getLatestAvailableAgentVersion } from './utils'; -type RunnerEnv = Record; - -async function withFleetAgent( - { getService }: FtrProviderContext, - runner: (runnerEnv: RunnerEnv) => RunnerEnv -) { - const log = getService('log'); - const config = getService('config'); - const kbnClient = getService('kibanaServer'); - - const elasticUrl = Url.format(config.get('servers.elasticsearch')); - const kibanaUrl = Url.format(config.get('servers.kibana')); - const fleetServerUrl = config.get('servers.fleetserver') - ? Url.format(config.get('servers.fleetserver')) - : undefined; - const username = config.get('servers.elasticsearch.username'); - const password = config.get('servers.elasticsearch.password'); - - await startRuntimeServices({ - log, - elasticUrl, - kibanaUrl, - fleetServerUrl, - username, - password, - version: await getLatestAvailableAgentVersion(kbnClient), - }); - - const fleetManager = new FleetManager(log); - const agentManager = new AgentManager(log); - - await fleetManager.setup(); - const agentVmName = await agentManager.setup(); - try { - await runner({ agentVmName }); - } finally { - agentManager.cleanup(); - fleetManager.cleanup(); - } -} - -export async function DefendWorkflowsCypressCliTestRunner(context: FtrProviderContext) { - return startDefendWorkflowsCypress(context, 'dw:run'); -} - -export async function DefendWorkflowsCypressVisualTestRunner(context: FtrProviderContext) { - return startDefendWorkflowsCypress(context, 'dw:open'); -} - -export async function DefendWorkflowsCypressEndpointTestRunner(context: FtrProviderContext) { - return withFleetAgent(context, (runnerEnv) => - startDefendWorkflowsCypress(context, 'dw:endpoint:open', runnerEnv) - ); -} - -function startDefendWorkflowsCypress( - context: FtrProviderContext, - cypressCommand: 'dw:endpoint:open' | 'dw:open' | 'dw:run', - runnerEnv?: RunnerEnv -) { +export function DefendWorkflowsCypressCliTestRunner(context: FtrProviderContext) { const config = context.getService('config'); return { @@ -87,6 +24,5 @@ function startDefendWorkflowsCypress( hostname: config.get('servers.kibana.hostname'), port: config.get('servers.kibana.port'), }), - ENDPOINT_VM_NAME: runnerEnv?.agentVmName, }; } diff --git a/x-pack/test/defend_workflows_cypress/utils.ts b/x-pack/test/defend_workflows_cypress/utils.ts deleted file mode 100644 index 2f13105f9b364..0000000000000 --- a/x-pack/test/defend_workflows_cypress/utils.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import axios from 'axios'; -import semver from 'semver'; -import { map } from 'lodash'; -import { KbnClient } from '@kbn/test'; - -/** - * Returns the Agent version that is available for install (will check `artifacts-api.elastic.co/v1/versions`) - * that is equal to or less than `maxVersion`. - * @param maxVersion - */ - -export const getLatestAvailableAgentVersion = async (kbnClient: KbnClient): Promise => { - const kbnStatus = await kbnClient.status.get(); - const agentVersions = await axios - .get('https://artifacts-api.elastic.co/v1/versions') - .then((response) => map(response.data.versions, (version) => version.split('-SNAPSHOT')[0])); - - let version = - semver.maxSatisfying(agentVersions, `<=${kbnStatus.version.number}`) ?? - kbnStatus.version.number; - - // Add `-SNAPSHOT` if version indicates it was from a snapshot or the build hash starts - // with `xxxxxxxxx` (value that seems to be present when running kibana from source) - if ( - kbnStatus.version.build_snapshot || - kbnStatus.version.build_hash.startsWith('XXXXXXXXXXXXXXX') - ) { - version += '-SNAPSHOT'; - } - - return version; -}; diff --git a/x-pack/test/defend_workflows_cypress/visual_config.ts b/x-pack/test/defend_workflows_cypress/visual_config.ts deleted file mode 100644 index 13e1ca4f7ef64..0000000000000 --- a/x-pack/test/defend_workflows_cypress/visual_config.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { FtrConfigProviderContext } from '@kbn/test'; - -import { DefendWorkflowsCypressVisualTestRunner } from './runner'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const defendWorkflowsCypressConfig = await readConfigFile(require.resolve('./config.ts')); - return { - ...defendWorkflowsCypressConfig.getAll(), - - testRunner: DefendWorkflowsCypressVisualTestRunner, - }; -} diff --git a/x-pack/test/osquery_cypress/runner.ts b/x-pack/test/osquery_cypress/runner.ts index 748567a52a8f8..fcead589247a6 100644 --- a/x-pack/test/osquery_cypress/runner.ts +++ b/x-pack/test/osquery_cypress/runner.ts @@ -12,7 +12,7 @@ import { FtrProviderContext } from './ftr_provider_context'; import { AgentManager } from './agent'; import { FleetManager } from './fleet_server'; -import { getLatestAvailableAgentVersion } from '../defend_workflows_cypress/utils'; +import { getLatestAvailableAgentVersion } from './utils'; async function setupFleetAgent({ getService }: FtrProviderContext) { const log = getService('log'); diff --git a/x-pack/test/osquery_cypress/utils.ts b/x-pack/test/osquery_cypress/utils.ts index 91dfd12ff2040..5fbbdd7131f53 100644 --- a/x-pack/test/osquery_cypress/utils.ts +++ b/x-pack/test/osquery_cypress/utils.ts @@ -5,6 +5,9 @@ * 2.0. */ +import axios from 'axios'; +import semver from 'semver'; +import { map } from 'lodash'; import { PackagePolicy, CreatePackagePolicyResponse } from '@kbn/fleet-plugin/common'; import { KbnClient } from '@kbn/test'; @@ -48,3 +51,31 @@ export const addIntegrationToAgentPolicy = async ( }, }); }; + +/** + * Returns the Agent version that is available for install (will check `artifacts-api.elastic.co/v1/versions`) + * that is equal to or less than `maxVersion`. + * @param maxVersion + */ + +export const getLatestAvailableAgentVersion = async (kbnClient: KbnClient): Promise => { + const kbnStatus = await kbnClient.status.get(); + const agentVersions = await axios + .get('https://artifacts-api.elastic.co/v1/versions') + .then((response) => map(response.data.versions, (version) => version.split('-SNAPSHOT')[0])); + + let version = + semver.maxSatisfying(agentVersions, `<=${kbnStatus.version.number}`) ?? + kbnStatus.version.number; + + // Add `-SNAPSHOT` if version indicates it was from a snapshot or the build hash starts + // with `xxxxxxxxx` (value that seems to be present when running kibana from source) + if ( + kbnStatus.version.build_snapshot || + kbnStatus.version.build_hash.startsWith('XXXXXXXXXXXXXXX') + ) { + version += '-SNAPSHOT'; + } + + return version; +}; From 8228c2afc2b3659589ba36f1416f4124210fdbec Mon Sep 17 00:00:00 2001 From: Sander Philipse <94373878+sphilipse@users.noreply.github.com> Date: Tue, 11 Jul 2023 18:06:01 +0800 Subject: [PATCH 05/97] [Enterprise Search] Remove GitHub connector and GCS native (#161620) ## Summary This removes the GitHub connector (which is not ready yet) and moves the Google Cloud Storage connector to non-native. --- .../common/connectors/connectors.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/x-pack/plugins/enterprise_search/common/connectors/connectors.ts b/x-pack/plugins/enterprise_search/common/connectors/connectors.ts index 30b8186c0053d..2883057a06a3b 100644 --- a/x-pack/plugins/enterprise_search/common/connectors/connectors.ts +++ b/x-pack/plugins/enterprise_search/common/connectors/connectors.ts @@ -51,7 +51,7 @@ export const CONNECTOR_DEFINITIONS: ConnectorServerSideDefinition[] = [ { iconPath: 'google_cloud_storage.svg', isBeta: true, - isNative: true, + isNative: false, keywords: ['google', 'cloud', 'blob', 's3', 'connector'], name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.googleCloud.name', { defaultMessage: 'Google Cloud Storage', @@ -140,17 +140,6 @@ export const CONNECTOR_DEFINITIONS: ConnectorServerSideDefinition[] = [ }), serviceType: 'dropbox', }, - { - iconPath: 'github.svg', - isBeta: true, - isNative: false, - isTechPreview: false, - keywords: ['github', 'cloud', 'server', 'connector'], - name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.github.name', { - defaultMessage: 'GitHub', - }), - serviceType: 'github', - }, { iconPath: 'oracle.svg', isBeta: true, From 7ea0dd6b116a93024d68ea2d93fa4ce90e9bf189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Tue, 11 Jul 2023 11:37:15 +0100 Subject: [PATCH 06/97] [TableListView] Fix dark mode for content editor (#161570) --- .../public/examples/msearch/msearch_app.tsx | 7 +------ .../src/__jest__/tests.helpers.tsx | 4 ++++ .../src/components/editor_loader.tsx | 17 ++++++++++++++--- .../content_editor/src/open_content_editor.tsx | 11 ++++++++--- .../content_editor/src/services.tsx | 9 +++++++++ .../src/__jest__/tests.helpers.tsx | 6 ++++-- .../table_list_view_table/src/services.tsx | 5 +++++ .../dashboard_listing/dashboard_listing.tsx | 2 ++ .../public/services/chrome/chrome.stub.ts | 3 ++- .../public/services/chrome/chrome_service.ts | 2 ++ .../dashboard/public/services/chrome/types.ts | 1 + 11 files changed, 52 insertions(+), 15 deletions(-) diff --git a/examples/content_management_examples/public/examples/msearch/msearch_app.tsx b/examples/content_management_examples/public/examples/msearch/msearch_app.tsx index ae05e15db91d0..2bb4ab1bf6fb9 100644 --- a/examples/content_management_examples/public/examples/msearch/msearch_app.tsx +++ b/examples/content_management_examples/public/examples/msearch/msearch_app.tsx @@ -24,12 +24,7 @@ export const MSearchApp = (props: { ) => { const services = { openFlyout: jest.fn(() => ({ @@ -21,6 +24,7 @@ export const getMockServices = (overrides?: Partial) => { TagList, TagSelector, notifyError: () => undefined, + theme$, ...overrides, }; diff --git a/packages/content-management/content_editor/src/components/editor_loader.tsx b/packages/content-management/content_editor/src/components/editor_loader.tsx index 63967624426fa..ee621949b5ba8 100644 --- a/packages/content-management/content_editor/src/components/editor_loader.tsx +++ b/packages/content-management/content_editor/src/components/editor_loader.tsx @@ -7,12 +7,21 @@ */ import React, { useState, useCallback, useEffect } from 'react'; -import { EuiFlyoutHeader, EuiFlyoutBody, EuiFlyoutFooter } from '@elastic/eui'; +import { EuiFlyoutHeader, EuiFlyoutBody, EuiFlyoutFooter, EuiThemeProvider } from '@elastic/eui'; +import useObservable from 'react-use/lib/useObservable'; +import { Observable, of } from 'rxjs'; +import { Theme } from '../services'; import type { Props } from './editor_flyout_content_container'; -export const ContentEditorLoader: React.FC = (props) => { +const themeDefault = { darkMode: false }; + +export const ContentEditorLoader: React.FC }> = ({ + theme$, + ...rest +}) => { const [Editor, setEditor] = useState | null>(null); + const { darkMode } = useObservable(theme$ ?? of(themeDefault), themeDefault); const loadEditor = useCallback(async () => { const { ContentEditorFlyoutContentContainer } = await import( @@ -27,7 +36,9 @@ export const ContentEditorLoader: React.FC = (props) => { }, [loadEditor]); return Editor ? ( - + + + ) : ( <> diff --git a/packages/content-management/content_editor/src/open_content_editor.tsx b/packages/content-management/content_editor/src/open_content_editor.tsx index 37d06be73aeb4..e2521eaa996c1 100644 --- a/packages/content-management/content_editor/src/open_content_editor.tsx +++ b/packages/content-management/content_editor/src/open_content_editor.tsx @@ -20,7 +20,7 @@ export type OpenContentEditorParams = Pick< export function useOpenContentEditor() { const services = useServices(); - const { openFlyout } = services; + const { openFlyout, theme$ } = services; const flyout = useRef(null); return useCallback( @@ -35,7 +35,12 @@ export function useOpenContentEditor() { }; flyout.current = openFlyout( - , + , { maxWidth: 600, size: 'm', @@ -46,6 +51,6 @@ export function useOpenContentEditor() { return closeFlyout; }, - [openFlyout, services] + [openFlyout, services, theme$] ); } diff --git a/packages/content-management/content_editor/src/services.tsx b/packages/content-management/content_editor/src/services.tsx index 831d9e05587d1..6b5536a2961e5 100644 --- a/packages/content-management/content_editor/src/services.tsx +++ b/packages/content-management/content_editor/src/services.tsx @@ -26,6 +26,10 @@ export interface SavedObjectsReference { type: string; } +export interface Theme { + readonly darkMode: boolean; +} + /** * Abstract external services for this component. */ @@ -34,6 +38,7 @@ export interface Services { notifyError: NotifyFn; TagList?: FC<{ references: SavedObjectsReference[] }>; TagSelector?: React.FC; + theme$: Observable; } const ContentEditorContext = React.createContext(null); @@ -59,6 +64,9 @@ export interface ContentEditorKibanaDependencies { addDanger: (notifyArgs: { title: MountPoint; text?: string }) => void; }; }; + theme: { + theme$: Observable; + }; }; /** * Handler from the '@kbn/kibana-react-plugin/public' Plugin @@ -131,6 +139,7 @@ export const ContentEditorKibanaProvider: FC = }} TagList={TagList} TagSelector={savedObjectsTagging?.ui.components.SavedObjectSaveModalTagSelector} + theme$={core.theme.theme$} > {children} diff --git a/packages/content-management/table_list_view_table/src/__jest__/tests.helpers.tsx b/packages/content-management/table_list_view_table/src/__jest__/tests.helpers.tsx index 5fb8b605d9202..a81ba92b07f5a 100644 --- a/packages/content-management/table_list_view_table/src/__jest__/tests.helpers.tsx +++ b/packages/content-management/table_list_view_table/src/__jest__/tests.helpers.tsx @@ -7,7 +7,7 @@ */ import React from 'react'; import type { ComponentType } from 'react'; -import { from } from 'rxjs'; +import { from, of } from 'rxjs'; import { ContentEditorProvider } from '@kbn/content-management-content-editor'; import { TagList } from '../mocks'; @@ -31,11 +31,13 @@ export const getMockServices = (overrides?: Partial) => { return services; }; +const theme$ = of({ darkMode: false }); + export function WithServices

(Comp: ComponentType

, overrides: Partial = {}) { return (props: P) => { const services = getMockServices(overrides); return ( - undefined}> + undefined} theme$={theme$}> diff --git a/packages/content-management/table_list_view_table/src/services.tsx b/packages/content-management/table_list_view_table/src/services.tsx index d7752a270c86c..5ee9f9d4b32bd 100644 --- a/packages/content-management/table_list_view_table/src/services.tsx +++ b/packages/content-management/table_list_view_table/src/services.tsx @@ -99,6 +99,11 @@ export interface TableListViewKibanaDependencies { overlays: { openFlyout(mount: MountPoint, options?: OverlayFlyoutOpenOptions): OverlayRef; }; + theme: { + theme$: Observable<{ + readonly darkMode: boolean; + }>; + }; }; /** * Handler from the '@kbn/kibana-react-plugin/public' Plugin diff --git a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.tsx b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.tsx index e39d323374fbc..1890e9ca37e5e 100644 --- a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.tsx @@ -87,6 +87,7 @@ export const DashboardListing = ({ notifications, overlays, http, + chrome: { theme }, savedObjectsTagging, dashboardSessionStorage, settings: { uiSettings }, @@ -223,6 +224,7 @@ export const DashboardListing = ({ notifications, overlays, http, + theme, }, toMountPoint, savedObjectsTagging: savedObjectsTaggingFakePlugin, diff --git a/src/plugins/dashboard/public/services/chrome/chrome.stub.ts b/src/plugins/dashboard/public/services/chrome/chrome.stub.ts index 74b534820ea8d..4a999157d39f8 100644 --- a/src/plugins/dashboard/public/services/chrome/chrome.stub.ts +++ b/src/plugins/dashboard/public/services/chrome/chrome.stub.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { chromeServiceMock } from '@kbn/core/public/mocks'; +import { coreMock, chromeServiceMock } from '@kbn/core/public/mocks'; import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; import { DashboardChromeService } from './types'; @@ -23,5 +23,6 @@ export const chromeServiceFactory: ChromeServiceFactory = () => { setBreadcrumbs: pluginMock.setBreadcrumbs, setHelpExtension: pluginMock.setHelpExtension, setIsVisible: pluginMock.setIsVisible, + theme: coreMock.createStart().theme, }; }; diff --git a/src/plugins/dashboard/public/services/chrome/chrome_service.ts b/src/plugins/dashboard/public/services/chrome/chrome_service.ts index f069ac3f95bd2..0364ce610451d 100644 --- a/src/plugins/dashboard/public/services/chrome/chrome_service.ts +++ b/src/plugins/dashboard/public/services/chrome/chrome_service.ts @@ -26,6 +26,7 @@ export const chromeServiceFactory: ChromeServiceFactory = ({ coreStart }) => { setHelpExtension, setIsVisible, }, + theme, } = coreStart; return { @@ -36,5 +37,6 @@ export const chromeServiceFactory: ChromeServiceFactory = ({ coreStart }) => { setBreadcrumbs, setHelpExtension, setIsVisible, + theme, }; }; diff --git a/src/plugins/dashboard/public/services/chrome/types.ts b/src/plugins/dashboard/public/services/chrome/types.ts index 2d3a1cffaae6a..ec8fa10962bfd 100644 --- a/src/plugins/dashboard/public/services/chrome/types.ts +++ b/src/plugins/dashboard/public/services/chrome/types.ts @@ -16,4 +16,5 @@ export interface DashboardChromeService { setBreadcrumbs: CoreStart['chrome']['setBreadcrumbs']; setHelpExtension: CoreStart['chrome']['setHelpExtension']; setIsVisible: CoreStart['chrome']['setIsVisible']; + theme: CoreStart['theme']; } From 203c9b04b66c4ef67de0b85f572305f43c358bd4 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Tue, 11 Jul 2023 12:49:58 +0200 Subject: [PATCH 07/97] [Defend Workflows] Fix response actions copy (#161615) --- x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts | 2 +- .../public/detection_engine/rule_response_actions/constants.ts | 2 +- .../rule_response_actions/endpoint/action_type_field.tsx | 2 +- .../rule_response_actions/endpoint/comment_field.tsx | 2 +- .../rule_response_actions/response_actions_header.tsx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts index 871909c865d6e..ef24db6909e4c 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts @@ -132,7 +132,7 @@ describe('Alert Event Details', () => { cy.getBySel('globalLoadingIndicator').should('not.exist'); closeDateTabIfVisible(); cy.getBySel('edit-rule-actions-tab').click(); - cy.contains('Response actions are run on each rule execution'); + cy.contains('Response actions are run on each rule execution.'); cy.getBySel(OSQUERY_RESPONSE_ACTION_ADD_BUTTON).click(); cy.getBySel(RESPONSE_ACTIONS_ITEM_0).within(() => { cy.contains('Query is a required field'); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/constants.ts index ee916820c7db5..9f0e6bbc3d7db 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/constants.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/constants.ts @@ -12,7 +12,7 @@ export const getActionDetails = (actionTypeId: string) => { case RESPONSE_ACTION_TYPES.OSQUERY: return { logo: 'logoOsquery', name: 'Osquery' }; case RESPONSE_ACTION_TYPES.ENDPOINT: - return { logo: 'logoSecurity', name: 'Endpoint' }; + return { logo: 'logoSecurity', name: 'Endpoint Security' }; // update when new responseActions are provided default: return { logo: 'logoOsquery', name: 'Osquery' }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/endpoint/action_type_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/endpoint/action_type_field.tsx index 32eae66855cf7..384facb4901fc 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/endpoint/action_type_field.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/endpoint/action_type_field.tsx @@ -74,7 +74,7 @@ const ActionTypeFieldComponent = ({ helpText: ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/endpoint/comment_field.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/endpoint/comment_field.tsx index e1f8546b9a562..1ae100103c76f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/endpoint/comment_field.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/endpoint/comment_field.tsx @@ -23,7 +23,7 @@ const CONFIG = { helpText: ( ), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_header.tsx index aa59b65a0c37a..8cab07ef08553 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_header.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_header.tsx @@ -49,7 +49,7 @@ export const ResponseActionsHeader = () => { From 91a0d2f4545babab15fc7f467f6b202eca4e9d8d Mon Sep 17 00:00:00 2001 From: Marta Bondyra <4283304+mbondyra@users.noreply.github.com> Date: Tue, 11 Jul 2023 13:05:03 +0200 Subject: [PATCH 08/97] [Lens] Refactor drag and drop (#161257) ## Summary When I created drag and drop for Lens, the API I went for was not the most readable one. It was designed this way because I wanted to gain some performance, but it was very hard to maintain the performance gain with a lot of changes in the drag and drop area because all the pieces of the code needed to memoized in a tricky way and it wasn't communicated well. In the end it works even without these tricks so I decided to simplify it in this PR. The main changes include: 1. Instead of multiple `useState` per parameter, we keep all the state in reducer both for `ReorderProvider` and `RootDragDropProvider`. Thanks to that we get multiple improvements: 2. The code in `DragDrop` component becomes more descriptive as we don't run multiple state updates when user executes an action but one state update describing what actually happens (eg. `dispatchDnd({type: 'selectDropTarget' ....})`. The internal logic of the update lives in the reducer. 3. We don't have to pass `trackUiCounterEvents` as another prop to `DragDrop` and run it wherever we need - instead we pass it as a middleware to the context and run before dispatching (and it's very easy to add more middlewares if we need extra integrations at some point!) 4. We also run a11y announcements as a middleware instead of inside `DragDrop` component 5. The `ChildDragDropProvider` props look much cleaner: before: ``` {children} ``` after: ``` {children} ``` 6. Created custom hook `useDragDropContext` instead of using `useContext(DragContext)` and making DragContext private. This way we will avoid potential problems with using context outside of root. 7. Bonus thing - if we ever decide to move to redux, the structure is there already What I am still not happy with is that the tests are very domain-dependant instead of user-driven - instead of checking the store actions, I should check the interface from the user perspective. I will try to work on it once I find some time between more important tasks though. --- .../public/example_drop_zone.tsx | 8 +- .../public/field_list_sidebar.tsx | 8 +- packages/kbn-dom-drag-drop/README.md | 14 +- packages/kbn-dom-drag-drop/index.ts | 6 +- .../kbn-dom-drag-drop/src/drag_drop.test.tsx | 747 ++++++++++-------- packages/kbn-dom-drag-drop/src/drag_drop.tsx | 499 +++++------- .../src/providers/announcements.tsx | 45 +- .../src/providers/providers.test.tsx | 8 +- .../src/providers/providers.tsx | 309 +++++--- .../src/providers/reorder_provider.tsx | 125 ++- .../kbn-dom-drag-drop/src/providers/types.tsx | 34 +- .../field_item_button/field_item_button.tsx | 1 + .../components/layout/discover_layout.tsx | 8 +- .../group_editor_controls/annotation_list.tsx | 116 ++- .../datasources/form_based/datapanel.test.tsx | 12 +- .../datasources/form_based/datapanel.tsx | 35 +- .../datasources/form_based/form_based.tsx | 62 +- .../public/datasources/form_based/mocks.ts | 16 - .../datasources/text_based/datapanel.test.tsx | 3 +- .../datasources/text_based/datapanel.tsx | 34 +- .../public/datasources/text_based/mocks.ts | 23 - .../text_based/text_based_languages.tsx | 47 +- .../buttons/draggable_dimension_button.tsx | 12 +- .../buttons/empty_dimension_button.tsx | 6 +- .../config_panel/layer_panel.test.tsx | 32 +- .../editor_frame/config_panel/layer_panel.tsx | 7 +- .../editor_frame/data_panel_wrapper.tsx | 14 +- .../editor_frame/editor_frame.test.tsx | 26 +- .../editor_frame/editor_frame.tsx | 10 +- .../workspace_panel/workspace_panel.test.tsx | 14 +- .../workspace_panel/workspace_panel.tsx | 16 +- x-pack/plugins/lens/public/mocks/index.ts | 18 + x-pack/plugins/lens/public/types.ts | 4 +- 33 files changed, 1209 insertions(+), 1110 deletions(-) delete mode 100644 x-pack/plugins/lens/public/datasources/text_based/mocks.ts diff --git a/examples/unified_field_list_examples/public/example_drop_zone.tsx b/examples/unified_field_list_examples/public/example_drop_zone.tsx index e1122d82ee30b..ba7c0ea4d630b 100644 --- a/examples/unified_field_list_examples/public/example_drop_zone.tsx +++ b/examples/unified_field_list_examples/public/example_drop_zone.tsx @@ -14,8 +14,8 @@ * Side Public License, v 1. */ -import React, { useContext, useMemo } from 'react'; -import { DragContext, DragDrop, DropOverlayWrapper, DropType } from '@kbn/dom-drag-drop'; +import React, { useMemo } from 'react'; +import { DragDrop, DropOverlayWrapper, DropType, useDragDropContext } from '@kbn/dom-drag-drop'; import { EuiEmptyPrompt, EuiPanel } from '@elastic/eui'; const DROP_PROPS = { @@ -34,8 +34,8 @@ export interface ExampleDropZoneProps { } export const ExampleDropZone: React.FC = ({ onDropField }) => { - const dragDropContext = useContext(DragContext); - const draggingFieldName = dragDropContext.dragging?.id; + const [{ dragging }] = useDragDropContext(); + const draggingFieldName = dragging?.id; const onDroppingField = useMemo(() => { if (!draggingFieldName) { diff --git a/examples/unified_field_list_examples/public/field_list_sidebar.tsx b/examples/unified_field_list_examples/public/field_list_sidebar.tsx index 6d2364a3a5613..121132e89b810 100644 --- a/examples/unified_field_list_examples/public/field_list_sidebar.tsx +++ b/examples/unified_field_list_examples/public/field_list_sidebar.tsx @@ -14,10 +14,10 @@ * Side Public License, v 1. */ -import React, { useCallback, useContext, useMemo, useRef } from 'react'; +import React, { useCallback, useMemo, useRef } from 'react'; import type { DataView } from '@kbn/data-views-plugin/public'; import { generateFilters } from '@kbn/data-plugin/public'; -import { ChildDragDropProvider, DragContext } from '@kbn/dom-drag-drop'; +import { ChildDragDropProvider, useDragDropContext } from '@kbn/dom-drag-drop'; import { UnifiedFieldListSidebarContainer, type UnifiedFieldListSidebarContainerProps, @@ -54,7 +54,7 @@ export const FieldListSidebar: React.FC = ({ onAddFieldToWorkspace, onRemoveFieldFromWorkspace, }) => { - const dragDropContext = useContext(DragContext); + const dragDropContext = useDragDropContext(); const unifiedFieldListContainerRef = useRef(null); const filterManager = services.data?.query?.filterManager; @@ -80,7 +80,7 @@ export const FieldListSidebar: React.FC = ({ }, [unifiedFieldListContainerRef]); return ( - + + ... your app here ... ``` @@ -17,13 +17,13 @@ First, place a RootDragDropProvider at the root of your application. If you have a child React application (e.g. a visualization), you will need to pass the drag / drop context down into it. This can be obtained like so: ```js -const context = useContext(DragContext); +const context = useDragDropContext(); ``` -In your child application, place a `ChildDragDropProvider` at the root of that, and spread the context into it: +In your child application, place a `ChildDragDropProvider` at the root of that, and assign the context into it: ```js -... your child app here ... +... your child app here ... ``` This enables your child application to share the same drag / drop context as the root application. @@ -49,7 +49,7 @@ To enable dragging an item, use `DragDrop` with both a `draggable` and a `value` To enable dropping, use `DragDrop` with both a `dropTypes` attribute that should be an array with at least one value and an `onDrop` handler attribute. `dropType` should only be truthy if is an item being dragged, and if a drop of the dragged item is supported. ```js -const { dragging } = useContext(DragContext); +const [ dndState ] = useDragDropContext() return ( ... elements from one group here ... +... elements from one group here ... ``` The children `DragDrop` components must have props defined as in the example: ```js - +

{fields.map((f) => ( { - const defaultContext = { - dataTestSubjPrefix: 'testDragDrop', + const defaultContextState = { dragging: undefined, - setDragging: jest.fn(), - setActiveDropTarget: jest.fn(), + dataTestSubjPrefix: 'testDragDrop', activeDropTarget: undefined, dropTargetsByOrder: undefined, keyboardMode: false, - setKeyboardMode: () => {}, - setA11yMessage: jest.fn(), - registerDropTarget: jest.fn(), }; const value = { @@ -104,16 +97,9 @@ describe('DragDrop', () => { }); test('dragstart sets dragging in the context and calls it with proper params', async () => { - const setDragging = jest.fn(); - - const setA11yMessage = jest.fn(); + const dndDispatch = jest.fn(); const component = mount( - + @@ -127,21 +113,24 @@ describe('DragDrop', () => { }); expect(dataTransfer.setData).toBeCalledWith('text', 'hello'); - expect(setDragging).toBeCalledWith({ ...value }); - expect(setA11yMessage).toBeCalledWith('Lifted hello'); + expect(dndDispatch).toBeCalledWith({ + type: 'startDragging', + payload: { dragging: value }, + }); }); test('drop resets all the things', async () => { const preventDefault = jest.fn(); const stopPropagation = jest.fn(); - const setDragging = jest.fn(); + const dndDispatch = jest.fn(); const onDrop = jest.fn(); const component = mount( @@ -151,25 +140,27 @@ describe('DragDrop', () => { const dragDrop = component.find('[data-test-subj="testDragDrop"]').at(0); dragDrop.simulate('dragOver'); + dndDispatch.mockClear(); dragDrop.simulate('drop', { preventDefault, stopPropagation }); expect(preventDefault).toBeCalled(); expect(stopPropagation).toBeCalled(); - expect(setDragging).toBeCalledWith(undefined); expect(onDrop).toBeCalledWith({ id: '2', humanData: { label: 'Label1' } }, 'field_add'); + expect(dndDispatch).toBeCalledWith({ type: 'resetState' }); }); test('drop function is not called on dropTypes undefined', async () => { const preventDefault = jest.fn(); const stopPropagation = jest.fn(); - const setDragging = jest.fn(); + const dndDispatch = jest.fn(); const onDrop = jest.fn(); const component = mount( @@ -183,7 +174,7 @@ describe('DragDrop', () => { expect(preventDefault).not.toHaveBeenCalled(); expect(stopPropagation).not.toHaveBeenCalled(); - expect(setDragging).not.toHaveBeenCalled(); + expect(dndDispatch).not.toHaveBeenCalled(); expect(onDrop).not.toHaveBeenCalled(); }); @@ -206,7 +197,7 @@ describe('DragDrop', () => { test('items that has dropTypes=undefined get special styling when another item is dragged', () => { const component = mount( - + @@ -228,17 +219,10 @@ describe('DragDrop', () => { let dragging: { id: '1'; humanData: { label: 'Label1' } } | undefined; const getAdditionalClassesOnEnter = jest.fn().mockReturnValue('additional'); const getAdditionalClassesOnDroppable = jest.fn().mockReturnValue('droppable'); - const setA11yMessage = jest.fn(); + const dndDispatch = jest.fn(); const component = mount( - { - dragging = { id: '1', humanData: { label: 'Label1' } }; - }} - > + { act(() => { jest.runAllTimers(); }); - expect(setA11yMessage).toBeCalledWith('Lifted ignored'); const dragDrop = component.find('[data-test-subj="testDragDrop"]').at(1); dragDrop.simulate('dragOver'); @@ -278,22 +261,20 @@ describe('DragDrop', () => { let dragging: { id: '1'; humanData: { label: 'Label1' } } | undefined; const getAdditionalClasses = jest.fn().mockReturnValue('additional'); const getAdditionalClassesOnDroppable = jest.fn().mockReturnValue('droppable'); - const setActiveDropTarget = jest.fn(); + const dndDispatch = jest.fn(() => { + dragging = { id: '1', humanData: { label: 'Label1' } }; + }); const component = mount( { - dragging = { id: '1', humanData: { label: 'Label1' } }; - }} - setActiveDropTarget={setActiveDropTarget} - activeDropTarget={value as DragContextState['activeDropTarget']} - keyboardMode={false} - setKeyboardMode={(keyboardMode) => true} - dropTargetsByOrder={undefined} - registerDropTarget={jest.fn()} + value={[ + { + ...defaultContextState, + dragging, + activeDropTarget: value as DragContextState['activeDropTarget'], + }, + dndDispatch, + ]} > { component.find('[data-test-subj="testDragDrop"]').at(1).simulate('dragover'); expect(component.find('.additional')).toHaveLength(2); component.find('[data-test-subj="testDragDrop"]').at(1).simulate('dragleave'); - expect(setActiveDropTarget).toBeCalledWith(undefined); + expect(dndDispatch).toBeCalledWith({ type: 'leaveDropTarget' }); }); describe('Keyboard navigation', () => { test('User receives proper drop Targets highlighted when pressing arrow keys', () => { const onDrop = jest.fn(); - const setActiveDropTarget = jest.fn(); - const setA11yMessage = jest.fn(); + const dndDispatch = jest.fn(); const items = [ { draggable: true, @@ -391,20 +371,21 @@ describe('DragDrop', () => { ]; const component = mount( , style: {} } }, - setActiveDropTarget, - setA11yMessage, - activeDropTarget: { ...items[1].value, onDrop, dropType: 'move_compatible' }, - dropTargetsByOrder: { - '2,0,1,0': { ...items[1].value, onDrop, dropType: 'move_compatible' }, - '2,0,2,0,0': { ...items[2].value, onDrop, dropType: 'replace_compatible' }, - '2,0,1,0,1': { ...items[1].value, onDrop, dropType: 'duplicate_compatible' }, - '2,0,1,0,2': { ...items[1].value, onDrop, dropType: 'swap_compatible' }, + value={[ + { + ...defaultContextState, + dragging: { ...items[0].value, ghost: { children:
, style: {} } }, + activeDropTarget: { ...items[1].value, onDrop, dropType: 'move_compatible' }, + dropTargetsByOrder: { + '2,0,1,0': { ...items[1].value, onDrop, dropType: 'move_compatible' }, + '2,0,2,0,0': { ...items[2].value, onDrop, dropType: 'replace_compatible' }, + '2,0,1,0,1': { ...items[1].value, onDrop, dropType: 'duplicate_compatible' }, + '2,0,1,0,2': { ...items[1].value, onDrop, dropType: 'swap_compatible' }, + }, + keyboardMode: true, }, - keyboardMode: true, - }} + dndDispatch, + ]} > {items.map((props) => ( @@ -418,17 +399,28 @@ describe('DragDrop', () => { .at(1) .simulate('focus'); + dndDispatch.mockClear(); + keyboardHandler.simulate('keydown', { key: 'ArrowRight' }); - expect(setActiveDropTarget).toBeCalledWith({ - ...items[2].value, - onDrop, - dropType: items[2].dropTypes![0], + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging: items[0].value, + dropTarget: { + ...items[2].value, + onDrop, + dropType: items[2].dropTypes![0], + }, + }, }); + + dndDispatch.mockClear(); + keyboardHandler.simulate('keydown', { key: 'Enter' }); - expect(setA11yMessage).toBeCalledWith( - `You're dragging Label1 from at position 1 in layer 0 over label3 from Y group at position 1 in layer 0. Press space or enter to replace label3 with Label1. Hold alt or option to duplicate. Hold shift to swap.` - ); - expect(setActiveDropTarget).toBeCalledWith(undefined); + expect(dndDispatch).toBeCalledWith({ + type: 'endDragging', + payload: { dragging: items[0].value }, + }); expect(onDrop).toBeCalledWith( { humanData: { label: 'Label1', position: 1, layerNumber: 0 }, id: '1' }, 'move_compatible' @@ -436,16 +428,17 @@ describe('DragDrop', () => { }); test('dragstart sets dragging in the context and calls it with proper params', async () => { - const setDragging = jest.fn(); - - const setA11yMessage = jest.fn(); + const dndDispatch = jest.fn(); const component = mount( @@ -463,23 +456,26 @@ describe('DragDrop', () => { jest.runAllTimers(); }); - expect(setDragging).toBeCalledWith({ - ...value, - ghost: { - children: , - style: { - minHeight: 0, - width: 0, + expect(dndDispatch).toBeCalledWith({ + type: 'startDragging', + payload: { + keyboardMode: true, + dragging: { + ...value, + ghost: { + children: , + style: { + minHeight: 0, + width: 0, + }, + }, }, }, }); - expect(setA11yMessage).toBeCalledWith('Lifted hello'); }); test('ActiveDropTarget gets ghost image', () => { const onDrop = jest.fn(); - const setActiveDropTarget = jest.fn(); - const setA11yMessage = jest.fn(); const items = [ { draggable: true, @@ -504,19 +500,22 @@ describe('DragDrop', () => { order: [2, 0, 1, 0], }, ]; + const dndDispatch = jest.fn(); const component = mount( Hello
, style: {} } }, - setActiveDropTarget, - setA11yMessage, - activeDropTarget: { ...items[1].value, onDrop, dropType: 'move_compatible' }, - dropTargetsByOrder: { - '2,0,1,0': { ...items[1].value, onDrop, dropType: 'move_compatible' }, + value={[ + { + ...defaultContextState, + dragging: { ...items[0].value, ghost: { children:
Hello
, style: {} } }, + + activeDropTarget: { ...items[1].value, onDrop, dropType: 'move_compatible' }, + dropTargetsByOrder: { + '2,0,1,0': { ...items[1].value, onDrop, dropType: 'move_compatible' }, + }, + keyboardMode: true, }, - keyboardMode: true, - }} + dndDispatch, + ]} > {items.map((props) => ( @@ -532,27 +531,25 @@ describe('DragDrop', () => { describe('multiple drop targets', () => { let activeDropTarget: DragContextState['activeDropTarget']; + const dragging = { id: '1', humanData: { label: 'Label1', layerNumber: 0 } }; const onDrop = jest.fn(); - let setActiveDropTarget = jest.fn(); - const setA11yMessage = jest.fn(); + let dndDispatch = jest.fn(); let component: ReactWrapper; beforeEach(() => { activeDropTarget = undefined; - setActiveDropTarget = jest.fn((val) => { + dndDispatch = jest.fn((val) => { activeDropTarget = value as DragContextState['activeDropTarget']; }); component = mount( true} - dropTargetsByOrder={undefined} - registerDropTarget={jest.fn()} + value={[ + { + ...defaultContextState, + dragging, + activeDropTarget, + }, + dndDispatch, + ]} > { .find('[data-test-subj="testDragDrop"]') .first() .simulate('dragstart', { dataTransfer }); - + dndDispatch.mockClear(); component.find('SingleDropInner').at(0).simulate('dragover'); - expect(setActiveDropTarget).toBeCalledWith({ - ...value, - dropType: 'move_compatible', - onDrop, + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging, + dropTarget: { + ...value, + dropType: 'move_compatible', + onDrop, + }, + }, }); + dndDispatch.mockClear(); component.find('SingleDropInner').at(1).simulate('dragover'); - - expect(setActiveDropTarget).toBeCalledWith({ - ...value, - dropType: 'duplicate_compatible', - onDrop, + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging, + dropTarget: { + ...value, + dropType: 'duplicate_compatible', + onDrop, + }, + }, }); + dndDispatch.mockClear(); component.find('SingleDropInner').at(2).simulate('dragover'); - expect(setActiveDropTarget).toBeCalledWith({ - ...value, - dropType: 'swap_compatible', - onDrop, + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging, + dropTarget: { + ...value, + dropType: 'swap_compatible', + onDrop, + }, + }, }); + dndDispatch.mockClear(); component.find('SingleDropInner').at(2).simulate('dragleave'); - expect(setActiveDropTarget).toBeCalledWith(undefined); + expect(dndDispatch).toBeCalledWith({ type: 'leaveDropTarget' }); }); test('drop on extra drop target passes correct dropType to onDrop', () => { @@ -673,10 +690,16 @@ describe('DragDrop', () => { .at(0) .simulate('dragover', { altKey: true }) .simulate('dragover', { altKey: true }); - expect(setActiveDropTarget).toBeCalledWith({ - ...value, - dropType: 'duplicate_compatible', - onDrop, + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging, + dropTarget: { + ...value, + dropType: 'duplicate_compatible', + onDrop, + }, + }, }); component @@ -684,10 +707,17 @@ describe('DragDrop', () => { .at(0) .simulate('dragover', { shiftKey: true }) .simulate('dragover', { shiftKey: true }); - expect(setActiveDropTarget).toBeCalledWith({ - ...value, - dropType: 'swap_compatible', - onDrop, + + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging, + dropTarget: { + ...value, + dropType: 'swap_compatible', + onDrop, + }, + }, }); }); @@ -702,8 +732,10 @@ describe('DragDrop', () => { extraDrop.simulate('dragover', { shiftKey: true }); extraDrop.simulate('dragover'); expect( - setActiveDropTarget.mock.calls.every((call) => call[0].dropType === 'duplicate_compatible') - ); + dndDispatch.mock.calls.every((call) => { + return call[0].payload.dropTarget.dropType === 'duplicate_compatible'; + }) + ).toBe(true); }); describe('keyboard navigation', () => { const items = [ @@ -781,26 +813,26 @@ describe('DragDrop', () => { }; test('when pressing enter key, context receives the proper dropTargetsByOrder', () => { let dropTargetsByOrder: DragContextState['dropTargetsByOrder'] = {}; - const setKeyboardMode = jest.fn(); + component = mount( , style: {} } }, - setDragging: jest.fn(), - setActiveDropTarget, - setA11yMessage, - activeDropTarget, - dropTargetsByOrder, - keyboardMode: true, - setKeyboardMode, - registerDropTarget: jest.fn((order, dropTarget) => { - dropTargetsByOrder = { - ...dropTargetsByOrder, - [order.join(',')]: dropTarget, - }; + value={[ + { + ...defaultContextState, + dragging: { ...items[0].value, ghost: { children:
, style: {} } }, + activeDropTarget, + dropTargetsByOrder, + keyboardMode: true, + }, + jest.fn((action) => { + if (action.type === 'registerDropTargets') { + dropTargetsByOrder = { + ...dropTargetsByOrder, + ...action.payload, + }; + } }), - }} + ]} > {items.map((props) => ( @@ -819,18 +851,16 @@ describe('DragDrop', () => { test('when pressing ArrowRight key with modifier key pressed in, the extra drop target is selected', () => { component = mount( , style: {} } }, - setDragging: jest.fn(), - setActiveDropTarget, - setA11yMessage, - activeDropTarget: undefined, - dropTargetsByOrder: assignedDropTargetsByOrder, - keyboardMode: true, - setKeyboardMode: jest.fn(), - registerDropTarget: jest.fn(), - }} + value={[ + { + ...defaultContextState, + dragging: { ...dragging, ghost: { children:
, style: {} } }, + activeDropTarget: undefined, + keyboardMode: true, + dropTargetsByOrder: assignedDropTargetsByOrder, + }, + dndDispatch, + ]} > {items.map((props) => ( @@ -839,44 +869,56 @@ describe('DragDrop', () => { ))} ); + dndDispatch.mockClear(); act(() => { component .find('[data-test-subj="testDragDrop-keyboardHandler"]') .at(1) .simulate('keydown', { key: 'ArrowRight', altKey: true }); }); - expect(setActiveDropTarget).toBeCalledWith({ - ...items[1].value, - onDrop, - dropType: 'duplicate_compatible', + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging: items[0].value, + dropTarget: { + ...items[1].value, + onDrop, + dropType: 'duplicate_compatible', + }, + }, }); + dndDispatch.mockClear(); act(() => { component .find('[data-test-subj="testDragDrop-keyboardHandler"]') .at(1) .simulate('keydown', { key: 'ArrowRight', shiftKey: true }); }); - expect(setActiveDropTarget).toBeCalledWith({ - ...items[1].value, - onDrop, - dropType: 'swap_compatible', + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging: items[0].value, + dropTarget: { + ...items[1].value, + onDrop, + dropType: 'swap_compatible', + }, + }, }); }); test('when having a main target selected and pressing alt, the first extra drop target is selected', () => { component = mount( , style: {} } }, - setDragging: jest.fn(), - setActiveDropTarget, - setA11yMessage, - activeDropTarget: assignedDropTargetsByOrder['2,0,1,0,0'], - dropTargetsByOrder: assignedDropTargetsByOrder, - keyboardMode: true, - setKeyboardMode: jest.fn(), - registerDropTarget: jest.fn(), - }} + value={[ + { + ...defaultContextState, + dragging: { ...items[0].value, ghost: { children:
, style: {} } }, + activeDropTarget: assignedDropTargetsByOrder['2,0,1,0,0'], + dropTargetsByOrder: assignedDropTargetsByOrder, + keyboardMode: true, + }, + dndDispatch, + ]} > {items.map((props) => ( @@ -885,44 +927,56 @@ describe('DragDrop', () => { ))} ); + dndDispatch.mockClear(); act(() => { component .find('[data-test-subj="testDragDrop-keyboardHandler"]') .at(1) .simulate('keydown', { key: 'Alt' }); }); - expect(setActiveDropTarget).toBeCalledWith({ - ...items[1].value, - onDrop, - dropType: 'duplicate_compatible', + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging: items[0].value, + dropTarget: { + ...items[1].value, + onDrop, + dropType: 'duplicate_compatible', + }, + }, }); + dndDispatch.mockClear(); act(() => { component .find('[data-test-subj="testDragDrop-keyboardHandler"]') .at(1) .simulate('keyup', { key: 'Alt' }); }); - expect(setActiveDropTarget).toBeCalledWith({ - ...items[1].value, - onDrop, - dropType: 'move_compatible', + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging: items[0].value, + dropTarget: { + ...items[1].value, + onDrop, + dropType: 'move_compatible', + }, + }, }); }); test('when having a main target selected and pressing shift, the second extra drop target is selected', () => { component = mount( , style: {} } }, - setDragging: jest.fn(), - setActiveDropTarget, - setA11yMessage, - activeDropTarget: assignedDropTargetsByOrder['2,0,1,0,0'], - dropTargetsByOrder: assignedDropTargetsByOrder, - keyboardMode: true, - setKeyboardMode: jest.fn(), - registerDropTarget: jest.fn(), - }} + value={[ + { + ...defaultContextState, + dragging: { ...items[0].value, ghost: { children:
, style: {} } }, + activeDropTarget: assignedDropTargetsByOrder['2,0,1,0,0'], + dropTargetsByOrder: assignedDropTargetsByOrder, + keyboardMode: true, + }, + dndDispatch, + ]} > {items.map((props) => ( @@ -931,6 +985,7 @@ describe('DragDrop', () => { ))} ); + dndDispatch.mockClear(); act(() => { component .find('[data-test-subj="testDragDrop-keyboardHandler"]') @@ -938,21 +993,34 @@ describe('DragDrop', () => { .simulate('keydown', { key: 'Shift' }); }); - expect(setActiveDropTarget).toBeCalledWith({ - ...items[1].value, - onDrop, - dropType: 'swap_compatible', + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging: items[0].value, + dropTarget: { + ...items[1].value, + onDrop, + dropType: 'swap_compatible', + }, + }, }); + dndDispatch.mockClear(); act(() => { component .find('[data-test-subj="testDragDrop-keyboardHandler"]') .at(1) .simulate('keyup', { key: 'Shift' }); }); - expect(setActiveDropTarget).toBeCalledWith({ - ...items[1].value, - onDrop, - dropType: 'move_compatible', + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging: items[0].value, + dropTarget: { + ...items[1].value, + onDrop, + dropType: 'move_compatible', + }, + }, }); }); }); @@ -979,34 +1047,10 @@ describe('DragDrop', () => { }, ]; const mountComponent = ( - dragContext: Partial | undefined, + dndContextState?: Partial, + dndDispatch?: Dispatch, onDropHandler?: () => void ) => { - let dragging = dragContext?.dragging; - let keyboardMode = !!dragContext?.keyboardMode; - let activeDropTarget = dragContext?.activeDropTarget; - - const setA11yMessage = jest.fn(); - const registerDropTarget = jest.fn(); - const baseContext = { - dataTestSubjPrefix: defaultContext.dataTestSubjPrefix, - dragging, - setDragging: (val?: DraggingIdentifier) => { - dragging = val; - }, - keyboardMode, - setKeyboardMode: jest.fn((mode) => { - keyboardMode = mode; - }), - setActiveDropTarget: (target?: DragDropIdentifier) => { - activeDropTarget = target as DropIdentifier; - }, - activeDropTarget, - setA11yMessage, - registerDropTarget, - dropTargetsByOrder: undefined, - }; - const dragDropSharedProps = { draggable: true, dragType: 'move' as 'copy' | 'move', @@ -1015,8 +1059,16 @@ describe('DragDrop', () => { }; return mount( - - + + { ); }; test(`Inactive group renders properly`, () => { - const component = mountComponent(undefined); + const component = mountComponent(); act(() => { jest.runAllTimers(); }); @@ -1054,13 +1106,8 @@ describe('DragDrop', () => { }); test(`Reorderable group with lifted element renders properly`, () => { - const setA11yMessage = jest.fn(); - const setDragging = jest.fn(); - const component = mountComponent({ - dragging: { ...items[0] }, - setDragging, - setA11yMessage, - }); + const dndDispatch = jest.fn(); + const component = mountComponent({ dragging: { ...items[0] } }, dndDispatch); act(() => { jest.runAllTimers(); @@ -1074,12 +1121,15 @@ describe('DragDrop', () => { jest.runAllTimers(); }); - expect(setDragging).toBeCalledWith({ ...items[0] }); - expect(setA11yMessage).toBeCalledWith('Lifted Label1'); + expect(dndDispatch).toBeCalledWith({ + type: 'startDragging', + payload: { dragging: { ...items[0] } }, + }); }); test(`Reordered elements get extra styles to show the reorder effect when dragging`, () => { - const component = mountComponent({ dragging: { ...items[0] } }); + const dndDispatch = jest.fn(); + const component = mountComponent({ dragging: { ...items[0] } }, dndDispatch); component .find('[data-test-subj="testDragDrop"]') @@ -1123,62 +1173,68 @@ describe('DragDrop', () => { test(`Dropping an item runs onDrop function`, () => { const preventDefault = jest.fn(); const stopPropagation = jest.fn(); - - const setA11yMessage = jest.fn(); - const setDragging = jest.fn(); - - const component = mountComponent({ - dragging: { ...items[0] }, - setDragging, - setA11yMessage, - }); + const dndDispatch = jest.fn(); + const component = mountComponent({ dragging: { ...items[0] } }, dndDispatch); const dragDrop = component.find('[data-test-subj="testDragDrop-reorderableDropLayer"]').at(1); dragDrop.simulate('dragOver'); + dndDispatch.mockClear(); dragDrop.simulate('drop', { preventDefault, stopPropagation }); act(() => { jest.runAllTimers(); }); - expect(setA11yMessage).toBeCalledWith( - 'Reordered Label1 in X group from position 1 to position 3' - ); + expect(dndDispatch).toBeCalledWith({ + type: 'dropToTarget', + payload: { + dragging: items[0], + dropTarget: { ...items[2], dropType: 'reorder' }, + }, + }); + expect(preventDefault).toBeCalled(); expect(stopPropagation).toBeCalled(); expect(onDrop).toBeCalledWith({ ...items[0] }, 'reorder'); }); test(`Keyboard Navigation: User cannot move an element outside of the group`, () => { - const setA11yMessage = jest.fn(); - const setActiveDropTarget = jest.fn(); - const component = mountComponent({ - dragging: { ...items[0] }, - keyboardMode: true, - activeDropTarget: undefined, - dropTargetsByOrder: { - '2,0,0': undefined, - '2,0,1': { ...items[1], onDrop, dropType: 'reorder' }, - '2,0,2': { ...items[2], onDrop, dropType: 'reorder' }, + const dndDispatch = jest.fn(); + const component = mountComponent( + { + dragging: { ...items[0] }, + keyboardMode: true, + activeDropTarget: undefined, + dropTargetsByOrder: { + '2,0,0': undefined, + '2,0,1': { ...items[1], onDrop, dropType: 'reorder' }, + '2,0,2': { ...items[2], onDrop, dropType: 'reorder' }, + }, }, - setActiveDropTarget, - setA11yMessage, - }); + dndDispatch + ); const keyboardHandler = component .find('[data-test-subj="testDragDrop-keyboardHandler"]') .at(1); + dndDispatch.mockClear(); keyboardHandler.simulate('keydown', { key: 'Space' }); keyboardHandler.simulate('keydown', { key: 'ArrowUp' }); - expect(setActiveDropTarget).not.toHaveBeenCalled(); + expect(dndDispatch).not.toHaveBeenCalled(); keyboardHandler.simulate('keydown', { key: 'Space' }); keyboardHandler.simulate('keydown', { key: 'ArrowDown' }); - expect(setActiveDropTarget).toBeCalledWith({ ...items[1], dropType: 'reorder' }); - expect(setA11yMessage).toBeCalledWith( - 'Reorder Label1 in X group from position 1 to position 2. Press space or enter to reorder' - ); + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dropTarget: { + ...items[1], + dropType: 'reorder', + }, + dragging: items[0], + }, + }); }); test(`Keyboard navigation: user can drop element to an activeDropTarget`, () => { @@ -1206,12 +1262,9 @@ describe('DragDrop', () => { }); test(`Keyboard Navigation: Doesn't call onDrop when movement is cancelled`, () => { - const setA11yMessage = jest.fn(); const onDropHandler = jest.fn(); - const component = mountComponent( - { dragging: { ...items[0] }, setA11yMessage }, - onDropHandler - ); + const dndDispatch = jest.fn(); + const component = mountComponent({ dragging: { ...items[0] } }, dndDispatch, onDropHandler); const keyboardHandler = component .find('[data-test-subj="testDragDrop-keyboardHandler"]') .at(1); @@ -1222,37 +1275,50 @@ describe('DragDrop', () => { }); expect(onDropHandler).not.toHaveBeenCalled(); - expect(setA11yMessage).toBeCalledWith( - 'Movement cancelled. Label1 returned to X group at position 1' - ); + + expect(dndDispatch).toBeCalledWith({ + type: 'endDragging', + payload: { + dragging: items[0], + }, + }); keyboardHandler.simulate('keydown', { key: 'Space' }); keyboardHandler.simulate('keydown', { key: 'ArrowDown' }); + dndDispatch.mockClear(); keyboardHandler.simulate('blur'); expect(onDropHandler).not.toHaveBeenCalled(); - expect(setA11yMessage).toBeCalledWith( - 'Movement cancelled. Label1 returned to X group at position 1' - ); + + expect(dndDispatch).toBeCalledWith({ + type: 'endDragging', + payload: { + dragging: items[0], + }, + }); }); test(`Keyboard Navigation: Reordered elements get extra styles to show the reorder effect`, () => { - const setA11yMessage = jest.fn(); - const component = mountComponent({ - dragging: { ...items[0] }, - keyboardMode: true, - activeDropTarget: undefined, - dropTargetsByOrder: { - '2,0,0': undefined, - '2,0,1': { ...items[1], onDrop, dropType: 'reorder' }, - '2,0,2': { ...items[2], onDrop, dropType: 'reorder' }, + const dndDispatch = jest.fn(); + const component = mountComponent( + { + dragging: { ...items[0] }, + keyboardMode: true, + activeDropTarget: undefined, + dropTargetsByOrder: { + '2,0,0': undefined, + '2,0,1': { ...items[1], onDrop, dropType: 'reorder' }, + '2,0,2': { ...items[2], onDrop, dropType: 'reorder' }, + }, }, - setA11yMessage, - }); + dndDispatch + ); const keyboardHandler = component .find('[data-test-subj="testDragDrop-keyboardHandler"]') .at(1); + keyboardHandler.simulate('keydown', { key: 'Space' }); + dndDispatch.mockClear(); keyboardHandler.simulate('keydown', { key: 'ArrowDown' }); expect( @@ -1268,9 +1334,14 @@ describe('DragDrop', () => { expect( component.find('[data-test-subj="testDragDrop-translatableDrop"]').at(1).prop('style') ).toEqual(undefined); - expect(setA11yMessage).toBeCalledWith( - 'Reorder Label1 in X group from position 1 to position 2. Press space or enter to reorder' - ); + + expect(dndDispatch).toBeCalledWith({ + type: 'selectDropTarget', + payload: { + dragging: items[0], + dropTarget: { ...items[1], onDrop, dropType: 'reorder' }, + }, + }); component .find('[data-test-subj="testDragDrop-reorderableDropLayer"]') @@ -1285,26 +1356,24 @@ describe('DragDrop', () => { }); test(`Keyboard Navigation: User cannot drop element to itself`, () => { - const setA11yMessage = jest.fn(); - const setActiveDropTarget = jest.fn(); + const dndDispatch = jest.fn(); + const contextState = { + ...defaultContextState, + keyboardMode: true, + activeDropTarget: { + ...items[1], + onDrop, + dropType: 'reorder' as const, + }, + dropTargetsByOrder: { + '2,0,1,0': undefined, + '2,0,1,1': { ...items[1], onDrop, dropType: 'reorder' as const }, + }, + dragging: { ...items[0] }, + }; const component = mount( - - + + { keyboardHandler.simulate('keydown', { key: 'Space' }); keyboardHandler.simulate('keydown', { key: 'ArrowUp' }); - expect(setActiveDropTarget).toBeCalledWith(undefined); - expect(setA11yMessage).toBeCalledWith('Label1 returned to its initial position 1'); + + expect(dndDispatch).toBeCalledWith({ + type: 'leaveDropTarget', + }); }); }); }); diff --git a/packages/kbn-dom-drag-drop/src/drag_drop.tsx b/packages/kbn-dom-drag-drop/src/drag_drop.tsx index ce3d6147d813f..66cb11bc15ad4 100644 --- a/packages/kbn-dom-drag-drop/src/drag_drop.tsx +++ b/packages/kbn-dom-drag-drop/src/drag_drop.tsx @@ -14,14 +14,14 @@ import useShallowCompareEffect from 'react-use/lib/useShallowCompareEffect'; import { DragDropIdentifier, DropIdentifier, - DragContext, - DragContextState, nextValidDropTarget, ReorderContext, - ReorderState, DropHandler, - announce, Ghost, + RegisteredDropTargets, + DragDropAction, + DragContextState, + useDragDropContext, } from './providers'; import { DropType } from './types'; import { REORDER_ITEM_MARGIN } from './constants'; @@ -63,11 +63,6 @@ interface BaseProps { */ value: DragDropIdentifier; - /** - * Optional comparison function to check whether a value is the dragged one - */ - isValueEqual?: (value1: unknown, value2: unknown) => boolean; - /** * The React element which will be passed the draggable handlers */ @@ -125,17 +120,13 @@ interface BaseProps { * The props for a draggable instance of that component. */ interface DragInnerProps extends BaseProps { - setKeyboardMode: DragContextState['setKeyboardMode']; - setDragging: DragContextState['setDragging']; - setActiveDropTarget: DragContextState['setActiveDropTarget']; - setA11yMessage: DragContextState['setA11yMessage']; + dndDispatch: React.Dispatch; + dataTestSubjPrefix?: string; activeDraggingProps?: { - keyboardMode: DragContextState['keyboardMode']; - activeDropTarget: DragContextState['activeDropTarget']; - dropTargetsByOrder: DragContextState['dropTargetsByOrder']; + keyboardMode: boolean; + activeDropTarget?: DropIdentifier; + dropTargetsByOrder: RegisteredDropTargets; }; - dataTestSubjPrefix: DragContextState['dataTestSubjPrefix']; - onTrackUICounterEvent: DragContextState['onTrackUICounterEvent'] | undefined; extraKeyboardHandler?: (e: KeyboardEvent) => void; ariaDescribedBy?: string; } @@ -144,16 +135,8 @@ interface DragInnerProps extends BaseProps { * The props for a non-draggable instance of that component. */ interface DropsInnerProps extends BaseProps { - dragging: DragContextState['dragging']; - keyboardMode: DragContextState['keyboardMode']; - setKeyboardMode: DragContextState['setKeyboardMode']; - setDragging: DragContextState['setDragging']; - setActiveDropTarget: DragContextState['setActiveDropTarget']; - setA11yMessage: DragContextState['setA11yMessage']; - registerDropTarget: DragContextState['registerDropTarget']; - activeDropTarget: DragContextState['activeDropTarget']; - dataTestSubjPrefix: DragContextState['dataTestSubjPrefix']; - onTrackUICounterEvent: DragContextState['onTrackUICounterEvent'] | undefined; + dndState: DragContextState; + dndDispatch: React.Dispatch; isNotDroppable: boolean; } @@ -165,19 +148,9 @@ const REORDER_OFFSET = REORDER_ITEM_MARGIN / 2; * @constructor */ export const DragDrop = (props: BaseProps) => { - const { - dragging, - setDragging, - keyboardMode, - registerDropTarget, - dropTargetsByOrder, - setKeyboardMode, - activeDropTarget, - setActiveDropTarget, - setA11yMessage, - dataTestSubjPrefix, - onTrackUICounterEvent, - } = useContext(DragContext); + const [dndState, dndDispatch] = useDragDropContext(); + + const { dragging, dropTargetsByOrder } = dndState; if (props.isDisabled) { return props.children; @@ -188,8 +161,8 @@ export const DragDrop = (props: BaseProps) => { const activeDraggingProps = isDragging ? { - keyboardMode, - activeDropTarget, + keyboardMode: dndState.keyboardMode, + activeDropTarget: dndState.activeDropTarget, dropTargetsByOrder, } : undefined; @@ -198,12 +171,8 @@ export const DragDrop = (props: BaseProps) => { const dragProps = { ...props, activeDraggingProps, - setKeyboardMode, - setDragging, - setActiveDropTarget, - setA11yMessage, - dataTestSubjPrefix, - onTrackUICounterEvent, + dataTestSubjPrefix: dndState.dataTestSubjPrefix, + dndDispatch, }; if (reorderableGroup && reorderableGroup.length > 1) { return ; @@ -214,16 +183,8 @@ export const DragDrop = (props: BaseProps) => { const dropProps = { ...props, - keyboardMode, - setKeyboardMode, - dragging, - setDragging, - activeDropTarget, - setActiveDropTarget, - registerDropTarget, - setA11yMessage, - dataTestSubjPrefix, - onTrackUICounterEvent, + dndState, + dndDispatch, isNotDroppable: // If the configuration has provided a droppable flag, but this particular item is not // droppable, then it should be less prominent. Ignores items that are both @@ -253,39 +214,35 @@ const DragInner = memo(function DragInner({ className, value, children, - setDragging, - setKeyboardMode, - setActiveDropTarget, + dndDispatch, order, activeDraggingProps, + dataTestSubjPrefix, dragType, onDragStart, onDragEnd, extraKeyboardHandler, ariaDescribedBy, - setA11yMessage, - dataTestSubjPrefix, - onTrackUICounterEvent, }: DragInnerProps) { - const keyboardMode = activeDraggingProps?.keyboardMode; - const activeDropTarget = activeDraggingProps?.activeDropTarget; - const dropTargetsByOrder = activeDraggingProps?.dropTargetsByOrder; + const { keyboardMode, activeDropTarget, dropTargetsByOrder } = activeDraggingProps || {}; const setTarget = useCallback( - (target?: DropIdentifier, announceModifierKeys = false) => { - setActiveDropTarget(target); - setA11yMessage( - target - ? announce.selectedTarget( - value.humanData, - target?.humanData, - target?.dropType, - announceModifierKeys - ) - : announce.noTarget() - ); + (target?: DropIdentifier) => { + if (!target) { + dndDispatch({ + type: 'leaveDropTarget', + }); + } else { + dndDispatch({ + type: 'selectDropTarget', + payload: { + dropTarget: target, + dragging: value, + }, + }); + } }, - [setActiveDropTarget, setA11yMessage, value.humanData] + [dndDispatch, value] ); const setTargetOfIndex = useCallback( @@ -293,11 +250,7 @@ const DragInner = memo(function DragInner({ const dropTargetsForActiveId = dropTargetsByOrder && Object.values(dropTargetsByOrder).filter((dropTarget) => dropTarget?.id === id); - if (index > 0 && dropTargetsForActiveId?.[index]) { - setTarget(dropTargetsForActiveId[index]); - } else { - setTarget(dropTargetsForActiveId?.[0], true); - } + setTarget(dropTargetsForActiveId?.[index]); }, [dropTargetsByOrder, setTarget] ); @@ -339,58 +292,64 @@ const DragInner = memo(function DragInner({ return { onKeyDown, onKeyUp }; }, [activeDropTarget, setTargetOfIndex]); - const dragStart = ( - e: DroppableEvent | KeyboardEvent, - keyboardModeOn?: boolean - ) => { - // Setting stopPropgagation causes Chrome failures, so - // we are manually checking if we've already handled this - // in a nested child, and doing nothing if so... - if (e && 'dataTransfer' in e && e.dataTransfer.getData('text')) { - return; - } + const dragStart = useCallback( + (e: DroppableEvent | KeyboardEvent, keyboardModeOn?: boolean) => { + // Setting stopPropgagation causes Chrome failures, so + // we are manually checking if we've already handled this + // in a nested child, and doing nothing if so... + if (e && 'dataTransfer' in e && e.dataTransfer.getData('text')) { + return; + } - // We only can reach the dragStart method if the element is draggable, - // so we know we have DraggableProps if we reach this code. - if (e && 'dataTransfer' in e) { - e.dataTransfer.setData('text', value.humanData.label); - } + // We only can reach the dragStart method if the element is draggable, + // so we know we have DraggableProps if we reach this code. + if (e && 'dataTransfer' in e) { + e.dataTransfer.setData('text', value.humanData.label); + } - // Chrome causes issues if you try to render from within a - // dragStart event, so we drop a setTimeout to avoid that. + // Chrome causes issues if you try to render from within a + // dragStart event, so we drop a setTimeout to avoid that. + + const currentTarget = e?.currentTarget; + + setTimeout(() => { + dndDispatch({ + type: 'startDragging', + payload: { + ...(keyboardModeOn ? { keyboardMode: true } : {}), + dragging: { + ...value, + ghost: keyboardModeOn + ? { + children, + style: { + width: currentTarget.offsetWidth, + minHeight: currentTarget?.offsetHeight, + }, + } + : undefined, + }, + }, + }); + onDragStart?.(currentTarget); + }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [dndDispatch, value, onDragStart] + ); - const currentTarget = e?.currentTarget; + const dragEnd = useCallback( + (e?: DroppableEvent) => { + e?.stopPropagation(); - setTimeout(() => { - setDragging({ - ...value, - ghost: keyboardModeOn - ? { - children, - style: { width: currentTarget.offsetWidth, minHeight: currentTarget?.offsetHeight }, - } - : undefined, + dndDispatch({ + type: 'endDragging', + payload: { dragging: value }, }); - setA11yMessage(announce.lifted(value.humanData)); - if (keyboardModeOn) { - setKeyboardMode(true); - } - if (onDragStart) { - onDragStart(currentTarget); - } - }); - }; - - const dragEnd = (e?: DroppableEvent) => { - e?.stopPropagation(); - setDragging(undefined); - setActiveDropTarget(undefined); - setKeyboardMode(false); - setA11yMessage(announce.cancelled(value.humanData)); - if (onDragEnd) { - onDragEnd(); - } - }; + onDragEnd?.(); + }, + [dndDispatch, value, onDragEnd] + ); const setNextTarget = (e: KeyboardEvent, reversed = false) => { const nextTarget = nextValidDropTarget( @@ -408,16 +367,23 @@ const DragInner = memo(function DragInner({ } else if (e.ctrlKey && nextTarget?.id) { setTargetOfIndex(nextTarget.id, 3); } else { - setTarget(nextTarget, true); + setTarget(nextTarget); } }; const dropToActiveDropTarget = () => { if (activeDropTarget) { - onTrackUICounterEvent?.('drop_total'); - const { dropType, humanData, onDrop: onTargetDrop } = activeDropTarget; - setTimeout(() => setA11yMessage(announce.dropped(value.humanData, humanData, dropType))); - onTargetDrop(value, dropType); + const { dropType, onDrop } = activeDropTarget; + setTimeout(() => { + dndDispatch({ + type: 'dropToTarget', + payload: { + dragging: value, + dropTarget: activeDropTarget, + }, + }); + }); + onDrop(value, dropType); } }; @@ -501,38 +467,35 @@ const DropsInner = memo(function DropsInner(props: DropsInnerProps) { value, children, draggable, - dragging, + dndState, + dndDispatch, isNotDroppable, dropTypes, order, getAdditionalClassesOnEnter, getAdditionalClassesOnDroppable, - activeDropTarget, - registerDropTarget, - setActiveDropTarget, - keyboardMode, - setKeyboardMode, - setDragging, - setA11yMessage, getCustomDropTarget, - dataTestSubjPrefix, } = props; + const { dragging, activeDropTarget, dataTestSubjPrefix, keyboardMode } = dndState; + const [isInZone, setIsInZone] = useState(false); const mainTargetRef = useRef(null); useShallowCompareEffect(() => { if (dropTypes && dropTypes?.[0] && onDrop && keyboardMode) { - dropTypes.forEach((dropType, index) => { - registerDropTarget([...order, index], { ...value, onDrop, dropType }); + dndDispatch({ + type: 'registerDropTargets', + payload: dropTypes.reduce( + (acc, dropType, index) => ({ + ...acc, + [[...props.order, index].join(',')]: { ...value, onDrop, dropType }, + }), + {} + ), }); - return () => { - dropTypes.forEach((_, index) => { - registerDropTarget([...order, index], undefined); - }); - }; } - }, [order, registerDropTarget, dropTypes, keyboardMode]); + }, [order, dndDispatch, dropTypes, keyboardMode]); useEffect(() => { let isMounted = true; @@ -586,15 +549,18 @@ const DropsInner = memo(function DropsInner(props: DropsInnerProps) { ); // An optimization to prevent a bunch of React churn. if (!isActiveDropTarget) { - setActiveDropTarget({ ...value, dropType: modifiedDropType, onDrop }); - setA11yMessage( - announce.selectedTarget(dragging.humanData, value.humanData, modifiedDropType) - ); + dndDispatch({ + type: 'selectDropTarget', + payload: { + dropTarget: { ...value, dropType: modifiedDropType, onDrop }, + dragging, + }, + }); } }; const dragLeave = () => { - setActiveDropTarget(undefined); + dndDispatch({ type: 'leaveDropTarget' }); }; const drop = (e: DroppableEvent, dropType: DropType) => { @@ -604,14 +570,17 @@ const DropsInner = memo(function DropsInner(props: DropsInnerProps) { if (onDrop && dragging) { const modifiedDropType = getModifiedDropType(e, dropType); onDrop(dragging, modifiedDropType); - setTimeout(() => - setA11yMessage(announce.dropped(dragging.humanData, value.humanData, modifiedDropType)) - ); + setTimeout(() => { + dndDispatch({ + type: 'dropToTarget', + payload: { + dragging, + dropTarget: { ...value, dropType: modifiedDropType, onDrop }, + }, + }); + }); } - - setDragging(undefined); - setActiveDropTarget(undefined); - setKeyboardMode(false); + dndDispatch({ type: 'resetState' }); }; const getProps = (dropType?: DropType, dropChildren?: ReactElement) => { @@ -746,23 +715,11 @@ const SingleDropInner = ({ const ReorderableDrag = memo(function ReorderableDrag( props: DragInnerProps & { reorderableGroup: Array<{ id: string }>; dragging?: DragDropIdentifier } ) { - const { - reorderState: { isReorderOn, reorderedItems, direction }, - setReorderState, - } = useContext(ReorderContext); + const [{ isReorderOn, reorderedItems, direction }, reorderDispatch] = useContext(ReorderContext); - const { - value, - setActiveDropTarget, - activeDraggingProps, - reorderableGroup, - setA11yMessage, - dataTestSubjPrefix, - } = props; + const { value, activeDraggingProps, reorderableGroup, dndDispatch, dataTestSubjPrefix } = props; - const keyboardMode = activeDraggingProps?.keyboardMode; - const activeDropTarget = activeDraggingProps?.activeDropTarget; - const dropTargetsByOrder = activeDraggingProps?.dropTargetsByOrder; + const { keyboardMode, activeDropTarget, dropTargetsByOrder } = activeDraggingProps || {}; const isDragging = !!activeDraggingProps; const isFocusInGroup = keyboardMode @@ -771,11 +728,11 @@ const ReorderableDrag = memo(function ReorderableDrag( : isDragging; useEffect(() => { - setReorderState((s: ReorderState) => ({ - ...s, - isReorderOn: isFocusInGroup, - })); - }, [setReorderState, isFocusInGroup]); + reorderDispatch({ + type: 'setIsReorderOn', + payload: isFocusInGroup, + }); + }, [reorderDispatch, isFocusInGroup]); const onReorderableDragStart = ( currentTarget?: @@ -783,24 +740,19 @@ const ReorderableDrag = memo(function ReorderableDrag( | KeyboardEvent['currentTarget'] ) => { if (currentTarget) { - const height = currentTarget.offsetHeight + REORDER_OFFSET; - setReorderState((s: ReorderState) => ({ - ...s, - draggingHeight: height, - })); + setTimeout(() => { + reorderDispatch({ + type: 'registerDraggingItemHeight', + payload: currentTarget.offsetHeight + REORDER_OFFSET, + }); + }); } }; const onReorderableDragEnd = () => { - resetReorderState(); + reorderDispatch({ type: 'reset' }); }; - const resetReorderState = () => - setReorderState((s: ReorderState) => ({ - ...s, - reorderedItems: [], - })); - const extraKeyboardHandler = (e: KeyboardEvent) => { if (isReorderOn && keyboardMode) { e.stopPropagation(); @@ -811,8 +763,7 @@ const ReorderableDrag = memo(function ReorderableDrag( if (index !== -1) activeDropTargetIndex = index; } if (e.key === keys.ARROW_LEFT || e.key === keys.ARROW_RIGHT) { - resetReorderState(); - setActiveDropTarget(undefined); + reorderDispatch({ type: 'reset' }); } else if (keys.ARROW_DOWN === e.key) { if (activeDropTargetIndex < reorderableGroup.length - 1) { const nextTarget = nextValidDropTarget( @@ -840,12 +791,8 @@ const ReorderableDrag = memo(function ReorderableDrag( const onReorderableDragOver = (target?: DropIdentifier) => { if (!target) { - setReorderState((s: ReorderState) => ({ - ...s, - reorderedItems: [], - })); - setA11yMessage(announce.selectedTarget(value.humanData, value.humanData, 'reorder')); - setActiveDropTarget(target); + reorderDispatch({ type: 'reset' }); + dndDispatch({ type: 'leaveDropTarget' }); return; } const droppingIndex = reorderableGroup.findIndex((i) => i.id === target.id); @@ -853,40 +800,34 @@ const ReorderableDrag = memo(function ReorderableDrag( if (draggingIndex === -1) { return; } - setActiveDropTarget(target); - - setA11yMessage(announce.selectedTarget(value.humanData, target.humanData, 'reorder')); - - setReorderState((s: ReorderState) => - draggingIndex < droppingIndex - ? { - ...s, - reorderedItems: reorderableGroup.slice(draggingIndex + 1, droppingIndex + 1), - direction: '-', - } - : { - ...s, - reorderedItems: reorderableGroup.slice(droppingIndex, draggingIndex), - direction: '+', - } - ); + + dndDispatch({ + type: 'selectDropTarget', + payload: { + dropTarget: target, + dragging: value, + }, + }); + reorderDispatch({ + type: 'setReorderedItems', + payload: { draggingIndex, droppingIndex, items: reorderableGroup }, + }); }; - const areItemsReordered = isDragging && keyboardMode && reorderedItems.length; + const areItemsReordered = keyboardMode && isDragging && reorderedItems.length; return (
acc + Number(cur.height || 0) + REORDER_OFFSET, + (acc, el) => acc + (el.height ?? 0) + REORDER_OFFSET, 0 )}px)`, } @@ -907,26 +848,13 @@ const ReorderableDrag = memo(function ReorderableDrag( const ReorderableDrop = memo(function ReorderableDrop( props: DropsInnerProps & { reorderableGroup: Array<{ id: string }> } ) { - const { - onDrop, - value, - dragging, - setDragging, - setKeyboardMode, - activeDropTarget, - setActiveDropTarget, - reorderableGroup, - setA11yMessage, - dataTestSubjPrefix, - onTrackUICounterEvent, - } = props; + const { onDrop, value, dndState, dndDispatch, reorderableGroup } = props; + const { dragging, dataTestSubjPrefix, activeDropTarget } = dndState; const currentIndex = reorderableGroup.findIndex((i) => i.id === value.id); - const { - reorderState: { isReorderOn, reorderedItems, draggingHeight, direction }, - setReorderState, - } = useContext(ReorderContext); + const [{ isReorderOn, reorderedItems, draggingHeight, direction }, reorderDispatch] = + useContext(ReorderContext); const heightRef = useRef(null); @@ -935,52 +863,38 @@ const ReorderableDrop = memo(function ReorderableDrop( useEffect(() => { if (isReordered && heightRef.current?.clientHeight) { - setReorderState((s) => ({ - ...s, - reorderedItems: s.reorderedItems.map((el) => - el.id === value.id - ? { - ...el, - height: heightRef.current?.clientHeight, - } - : el - ), - })); + reorderDispatch({ + type: 'registerReorderedItemHeight', + payload: { id: value.id, height: heightRef.current.clientHeight }, + }); } - }, [isReordered, setReorderState, value.id]); + }, [isReordered, reorderDispatch, value.id]); const onReorderableDragOver = (e: DroppableEvent) => { e.preventDefault(); // An optimization to prevent a bunch of React churn. if (activeDropTarget?.id !== value?.id && onDrop) { - setActiveDropTarget({ ...value, dropType: 'reorder', onDrop }); - const draggingIndex = reorderableGroup.findIndex((i) => i.id === dragging?.id); - if (!dragging || draggingIndex === -1) { return; } + const droppingIndex = currentIndex; if (draggingIndex === droppingIndex) { - setReorderState((s: ReorderState) => ({ - ...s, - reorderedItems: [], - })); + reorderDispatch({ type: 'reset' }); } - setReorderState((s: ReorderState) => - draggingIndex < droppingIndex - ? { - ...s, - reorderedItems: reorderableGroup.slice(draggingIndex + 1, droppingIndex + 1), - direction: '-', - } - : { - ...s, - reorderedItems: reorderableGroup.slice(droppingIndex, draggingIndex), - direction: '+', - } - ); + reorderDispatch({ + type: 'setReorderedItems', + payload: { draggingIndex, droppingIndex, items: reorderableGroup }, + }); + dndDispatch({ + type: 'selectDropTarget', + payload: { + dropTarget: { ...value, dropType: 'reorder', onDrop }, + dragging, + }, + }); } }; @@ -988,18 +902,20 @@ const ReorderableDrop = memo(function ReorderableDrop( e.preventDefault(); e.stopPropagation(); - setActiveDropTarget(undefined); - setDragging(undefined); - setKeyboardMode(false); - if (onDrop && dragging) { - onTrackUICounterEvent?.('drop_total'); onDrop(dragging, 'reorder'); // setTimeout ensures it will run after dragEnd messaging - setTimeout(() => - setA11yMessage(announce.dropped(dragging.humanData, value.humanData, 'reorder')) - ); + setTimeout(() => { + dndDispatch({ + type: 'dropToTarget', + payload: { + dragging, + dropTarget: { ...value, dropType: 'reorder', onDrop }, + }, + }); + }); } + dndDispatch({ type: 'resetState' }); }; return ( @@ -1027,11 +943,8 @@ const ReorderableDrop = memo(function ReorderableDrop( onDrop={onReorderableDrop} onDragOver={onReorderableDragOver} onDragLeave={() => { - setActiveDropTarget(undefined); - setReorderState((s: ReorderState) => ({ - ...s, - reorderedItems: [], - })); + dndDispatch({ type: 'leaveDropTarget' }); + reorderDispatch({ type: 'reset' }); }} />
diff --git a/packages/kbn-dom-drag-drop/src/providers/announcements.tsx b/packages/kbn-dom-drag-drop/src/providers/announcements.tsx index f3d5c97f57023..442aff7718780 100644 --- a/packages/kbn-dom-drag-drop/src/providers/announcements.tsx +++ b/packages/kbn-dom-drag-drop/src/providers/announcements.tsx @@ -10,11 +10,7 @@ import { i18n } from '@kbn/i18n'; import { DropType } from '../types'; import { HumanData } from '.'; -type AnnouncementFunction = ( - draggedElement: HumanData, - dropElement: HumanData, - announceModifierKeys?: boolean -) => string; +type AnnouncementFunction = (draggedElement: HumanData, dropElement: HumanData) => string; interface CustomAnnouncementsType { dropped: Partial<{ [dropType in DropType]: AnnouncementFunction }>; @@ -32,10 +28,9 @@ const replaceAnnouncement = { canDuplicate, canCombine, layerNumber: dropLayerNumber, - }: HumanData, - announceModifierKeys?: boolean + }: HumanData ) => { - if (announceModifierKeys && (canSwap || canDuplicate)) { + if (canSwap || canDuplicate) { return i18n.translate('domDragDrop.announce.selectedTarget.replaceMain', { defaultMessage: `You're dragging {label} from {groupLabel} at position {position} in layer {layerNumber} over {dropLabel} from {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to replace {dropLabel} with {label}.{duplicateCopy}{swapCopy}{combineCopy}`, values: { @@ -168,10 +163,9 @@ const combineAnnouncement = { canDuplicate, canCombine, layerNumber: dropLayerNumber, - }: HumanData, - announceModifierKeys?: boolean + }: HumanData ) => { - if (announceModifierKeys && (canSwap || canDuplicate || canCombine)) { + if (canSwap || canDuplicate || canCombine) { return i18n.translate('domDragDrop.announce.selectedTarget.combineMain', { defaultMessage: `You're dragging {label} from {groupLabel} at position {position} in layer {layerNumber} over {dropLabel} from {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to combine {dropLabel} with {label}.{duplicateCopy}{swapCopy}{combineCopy}`, values: { @@ -247,10 +241,9 @@ export const announcements: CustomAnnouncementsType = { canDuplicate, canCombine, layerNumber: dropLayerNumber, - }: HumanData, - announceModifierKeys?: boolean + }: HumanData ) => { - if (announceModifierKeys && (canSwap || canDuplicate || canCombine)) { + if (canSwap || canDuplicate || canCombine) { return i18n.translate('domDragDrop.announce.selectedTarget.replaceIncompatibleMain', { defaultMessage: `You're dragging {label} from {groupLabel} at position {position} in layer {layerNumber} over {dropLabel} from {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to convert {label} to {nextLabel} and replace {dropLabel}.{duplicateCopy}{swapCopy}{combineCopy}`, values: { @@ -290,10 +283,9 @@ export const announcements: CustomAnnouncementsType = { canSwap, canDuplicate, layerNumber: dropLayerNumber, - }: HumanData, - announceModifierKeys?: boolean + }: HumanData ) => { - if (announceModifierKeys && (canSwap || canDuplicate)) { + if (canSwap || canDuplicate) { return i18n.translate('domDragDrop.announce.selectedTarget.moveIncompatibleMain', { defaultMessage: `You're dragging {label} from {groupLabel} at position {position} in layer {layerNumber} over position {dropPosition} in {dropGroupLabel} group in layer {dropLayerNumber}. Press space or enter to convert {label} to {nextLabel} and move.{duplicateCopy}`, values: { @@ -329,10 +321,9 @@ export const announcements: CustomAnnouncementsType = { canSwap, canDuplicate, layerNumber: dropLayerNumber, - }: HumanData, - announceModifierKeys?: boolean + }: HumanData ) => { - if (announceModifierKeys && (canSwap || canDuplicate)) { + if (canSwap || canDuplicate) { return i18n.translate('domDragDrop.announce.selectedTarget.moveCompatibleMain', { defaultMessage: `You're dragging {label} from {groupLabel} at position {position} over position {dropPosition} in {dropGroupLabel} group in layer {dropLayerNumber}. Press space or enter to move.{duplicateCopy}`, values: { @@ -790,19 +781,9 @@ export const announce = { dropped: (draggedElement: HumanData, dropElement: HumanData, type?: DropType) => (type && announcements.dropped?.[type]?.(draggedElement, dropElement)) || defaultAnnouncements.dropped(draggedElement, dropElement), - selectedTarget: ( - draggedElement: HumanData, - dropElement: HumanData, - type?: DropType, - announceModifierKeys?: boolean - ) => { + selectedTarget: (draggedElement: HumanData, dropElement: HumanData, type?: DropType) => { return ( - (type && - announcements.selectedTarget?.[type]?.( - draggedElement, - dropElement, - announceModifierKeys - )) || + (type && announcements.selectedTarget?.[type]?.(draggedElement, dropElement)) || defaultAnnouncements.selectedTarget(draggedElement, dropElement) ); }, diff --git a/packages/kbn-dom-drag-drop/src/providers/providers.test.tsx b/packages/kbn-dom-drag-drop/src/providers/providers.test.tsx index 0bb255e9ac15d..06aceb603025a 100644 --- a/packages/kbn-dom-drag-drop/src/providers/providers.test.tsx +++ b/packages/kbn-dom-drag-drop/src/providers/providers.test.tsx @@ -6,9 +6,9 @@ * Side Public License, v 1. */ -import React, { useContext } from 'react'; +import React from 'react'; import { mount } from 'enzyme'; -import { RootDragDropProvider, DragContext } from '.'; +import { RootDragDropProvider, useDragDropContext } from '.'; jest.useFakeTimers({ legacyFakeTimers: true }); @@ -16,11 +16,11 @@ describe('RootDragDropProvider', () => { test('reuses contexts for each render', () => { const contexts: Array<{}> = []; const TestComponent = ({ name }: { name: string }) => { - const context = useContext(DragContext); + const context = useDragDropContext(); contexts.push(context); return (
- {name} {!!context.dragging} + {name} {!!context[0].dragging}
); }; diff --git a/packages/kbn-dom-drag-drop/src/providers/providers.tsx b/packages/kbn-dom-drag-drop/src/providers/providers.tsx index d1c4f5f23dd8f..a036d65d75bc2 100644 --- a/packages/kbn-dom-drag-drop/src/providers/providers.tsx +++ b/packages/kbn-dom-drag-drop/src/providers/providers.tsx @@ -6,45 +6,54 @@ * Side Public License, v 1. */ -import React, { useState, useMemo } from 'react'; +import React, { Reducer, useReducer } from 'react'; import { EuiScreenReaderOnly } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DropIdentifier, - DraggingIdentifier, DragDropIdentifier, RegisteredDropTargets, + DragContextValue, DragContextState, + CustomMiddleware, + DraggingIdentifier, } from './types'; import { DEFAULT_DATA_TEST_SUBJ } from '../constants'; +import { announce } from './announcements'; +const initialState = { + dragging: undefined, + activeDropTarget: undefined, + keyboardMode: false, + dropTargetsByOrder: {}, + dataTestSubjPrefix: DEFAULT_DATA_TEST_SUBJ, +}; /** * The drag / drop context singleton, used like so: * - * const { dragging, setDragging } = useContext(DragContext); + * const [ state, dispatch ] = useDragDropContext(); */ -export const DragContext = React.createContext({ - dragging: undefined, - setDragging: () => {}, - keyboardMode: false, - setKeyboardMode: () => {}, - activeDropTarget: undefined, - setActiveDropTarget: () => {}, - setA11yMessage: () => {}, - dropTargetsByOrder: undefined, - registerDropTarget: () => {}, - dataTestSubjPrefix: DEFAULT_DATA_TEST_SUBJ, - onTrackUICounterEvent: undefined, -}); +const DragContext = React.createContext([initialState, () => {}]); + +export function useDragDropContext() { + const context = React.useContext(DragContext); + if (context === undefined) { + throw new Error( + 'useDragDropContext must be used within a or ' + ); + } + return context; +} /** * The argument to DragDropProvider. */ -export interface ProviderProps extends DragContextState { +export interface ProviderProps { /** * The React children. */ children: React.ReactNode; + value: DragContextValue; } /** @@ -54,74 +63,193 @@ export interface ProviderProps extends DragContextState { * * @param props */ + +interface ResetStateAction { + type: 'resetState'; + payload?: string; +} + +interface EndDraggingAction { + type: 'endDragging'; + payload: { + dragging: DraggingIdentifier; + }; +} + +interface StartDraggingAction { + type: 'startDragging'; + payload: { + dragging: DraggingIdentifier; + keyboardMode?: boolean; + }; +} + +interface LeaveDropTargetAction { + type: 'leaveDropTarget'; +} + +interface SelectDropTargetAction { + type: 'selectDropTarget'; + payload: { + dropTarget: DropIdentifier; + dragging: DragDropIdentifier; + }; +} + +interface DragToTargetAction { + type: 'dropToTarget'; + payload: { + dragging: DragDropIdentifier; + dropTarget: DropIdentifier; + }; +} + +interface RegisterDropTargetAction { + type: 'registerDropTargets'; + payload: RegisteredDropTargets; +} + +export type DragDropAction = + | ResetStateAction + | RegisterDropTargetAction + | LeaveDropTargetAction + | SelectDropTargetAction + | DragToTargetAction + | StartDraggingAction + | EndDraggingAction; + +const dragDropReducer = (state: DragContextState, action: DragDropAction) => { + switch (action.type) { + case 'resetState': + case 'endDragging': + return { + ...state, + dropTargetsByOrder: undefined, + dragging: undefined, + keyboardMode: false, + activeDropTarget: undefined, + }; + case 'registerDropTargets': + return { + ...state, + dropTargetsByOrder: { + ...state.dropTargetsByOrder, + ...action.payload, + }, + }; + case 'dropToTarget': + return { + ...state, + dropTargetsByOrder: undefined, + dragging: undefined, + keyboardMode: false, + activeDropTarget: undefined, + }; + case 'leaveDropTarget': + return { + ...state, + activeDropTarget: undefined, + }; + case 'selectDropTarget': + return { + ...state, + activeDropTarget: action.payload.dropTarget, + }; + case 'startDragging': + return { + ...state, + ...action.payload, + }; + default: + return state; + } +}; + +const useReducerWithMiddleware = ( + reducer: Reducer, + initState: DragContextState, + middlewareFns?: Array<(action: DragDropAction) => void> +) => { + const [state, dispatch] = useReducer(reducer, initState); + + const dispatchWithMiddleware = React.useCallback( + (action: DragDropAction) => { + if (middlewareFns !== undefined && middlewareFns.length > 0) { + middlewareFns.forEach((middlewareFn) => middlewareFn(action)); + } + dispatch(action); + }, + [middlewareFns] + ); + + return [state, dispatchWithMiddleware] as const; +}; + +const useA11yMiddleware = () => { + const [a11yMessage, setA11yMessage] = React.useState(''); + const a11yMiddleware = React.useCallback((action: DragDropAction) => { + switch (action.type) { + case 'startDragging': + setA11yMessage(announce.lifted(action.payload.dragging.humanData)); + return; + case 'selectDropTarget': + setA11yMessage( + announce.selectedTarget( + action.payload.dragging.humanData, + action.payload.dropTarget.humanData, + action.payload.dropTarget.dropType + ) + ); + return; + case 'leaveDropTarget': + setA11yMessage(announce.noTarget()); + return; + case 'dropToTarget': + const { dragging, dropTarget } = action.payload; + setA11yMessage( + announce.dropped(dragging.humanData, dropTarget.humanData, dropTarget.dropType) + ); + return; + case 'endDragging': + setA11yMessage(announce.cancelled(action.payload.dragging.humanData)); + return; + default: + return; + } + }, []); + return { a11yMessage, a11yMiddleware }; +}; + export function RootDragDropProvider({ children, dataTestSubj = DEFAULT_DATA_TEST_SUBJ, - onTrackUICounterEvent, + customMiddleware, }: { children: React.ReactNode; dataTestSubj?: string; - onTrackUICounterEvent?: DragContextState['onTrackUICounterEvent']; + customMiddleware?: CustomMiddleware; }) { - const [draggingState, setDraggingState] = useState<{ dragging?: DraggingIdentifier }>({ - dragging: undefined, - }); - const [keyboardModeState, setKeyboardModeState] = useState(false); - const [a11yMessageState, setA11yMessageState] = useState(''); - const [activeDropTargetState, setActiveDropTargetState] = useState( - undefined - ); - - const [dropTargetsByOrderState, setDropTargetsByOrderState] = useState({}); - - const setDragging = useMemo( - () => (dragging?: DraggingIdentifier) => setDraggingState({ dragging }), - [setDraggingState] - ); + const { a11yMessage, a11yMiddleware } = useA11yMiddleware(); + const middlewareFns = React.useMemo(() => { + return customMiddleware ? [customMiddleware, a11yMiddleware] : [a11yMiddleware]; + }, [customMiddleware, a11yMiddleware]); - const setA11yMessage = useMemo( - () => (message: string) => setA11yMessageState(message), - [setA11yMessageState] - ); - - const setActiveDropTarget = useMemo( - () => (activeDropTarget?: DropIdentifier) => setActiveDropTargetState(activeDropTarget), - [setActiveDropTargetState] - ); - - const registerDropTarget = useMemo( - () => (order: number[], dropTarget?: DropIdentifier) => { - return setDropTargetsByOrderState((s) => { - return { - ...s, - [order.join(',')]: dropTarget, - }; - }); + const [state, dispatch] = useReducerWithMiddleware( + dragDropReducer, + { + ...initialState, + dataTestSubjPrefix: dataTestSubj, }, - [setDropTargetsByOrderState] + middlewareFns ); return ( <> - - {children} - + {children}

- {a11yMessageState} + {a11yMessage}

{i18n.translate('domDragDrop.keyboardInstructionsReorder', { @@ -206,47 +334,6 @@ export function nextValidDropTarget( * * @param props */ -export function ChildDragDropProvider({ - dragging, - setDragging, - setKeyboardMode, - keyboardMode, - activeDropTarget, - setActiveDropTarget, - setA11yMessage, - registerDropTarget, - dropTargetsByOrder, - dataTestSubjPrefix, - onTrackUICounterEvent, - children, -}: ProviderProps) { - const value = useMemo( - () => ({ - setKeyboardMode, - keyboardMode, - dragging, - setDragging, - activeDropTarget, - setActiveDropTarget, - setA11yMessage, - dropTargetsByOrder, - registerDropTarget, - dataTestSubjPrefix, - onTrackUICounterEvent, - }), - [ - setDragging, - dragging, - activeDropTarget, - setActiveDropTarget, - setKeyboardMode, - keyboardMode, - setA11yMessage, - dropTargetsByOrder, - registerDropTarget, - dataTestSubjPrefix, - onTrackUICounterEvent, - ] - ); +export function ChildDragDropProvider({ value, children }: ProviderProps) { return {children}; } diff --git a/packages/kbn-dom-drag-drop/src/providers/reorder_provider.tsx b/packages/kbn-dom-drag-drop/src/providers/reorder_provider.tsx index c2aa11eb8bc8d..814aecf4d08e1 100644 --- a/packages/kbn-dom-drag-drop/src/providers/reorder_provider.tsx +++ b/packages/kbn-dom-drag-drop/src/providers/reorder_provider.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { useState, useMemo } from 'react'; +import React, { useReducer, Reducer, Dispatch } from 'react'; import classNames from 'classnames'; import { DEFAULT_DATA_TEST_SUBJ, REORDER_ITEM_HEIGHT } from '../constants'; @@ -31,69 +31,116 @@ export interface ReorderState { * indicates that user is in keyboard mode */ isReorderOn: boolean; - /** - * reorder group needed for screen reader aria-described-by attribute - */ - groupId: string; } -type SetReorderStateDispatch = (prevState: ReorderState) => ReorderState; +const initialState: ReorderState = { + reorderedItems: [], + direction: '-' as const, + draggingHeight: REORDER_ITEM_HEIGHT, + isReorderOn: false, +}; /** * Reorder context state */ -export interface ReorderContextState { - reorderState: ReorderState; - setReorderState: (dispatch: SetReorderStateDispatch) => void; -} +export type ReorderContextState = [ReorderState, Dispatch]; /** * Reorder context */ -export const ReorderContext = React.createContext({ - reorderState: { - reorderedItems: [], - direction: '-', - draggingHeight: REORDER_ITEM_HEIGHT, - isReorderOn: false, - groupId: '', - }, - setReorderState: () => () => {}, -}); +export const ReorderContext = React.createContext([ + initialState, + () => () => {}, +]); /** * To create a reordering group, surround the elements from the same group with a `ReorderProvider` - * @param id * @param children * @param className - * @param draggingHeight * @param dataTestSubj * @constructor */ + +interface ResetAction { + type: 'reset'; +} + +interface RegisterDraggingItemHeightAction { + type: 'registerDraggingItemHeight'; + payload: number; +} + +interface RegisterReorderedItemHeightAction { + type: 'registerReorderedItemHeight'; + payload: { id: string; height: number }; +} + +interface SetIsReorderOnAction { + type: 'setIsReorderOn'; + payload: boolean; +} + +interface SetReorderedItemsAction { + type: 'setReorderedItems'; + payload: { + items: ReorderState['reorderedItems']; + draggingIndex: number; + droppingIndex: number; + }; +} + +type ReorderAction = + | ResetAction + | RegisterDraggingItemHeightAction + | RegisterReorderedItemHeightAction + | SetIsReorderOnAction + | SetReorderedItemsAction; + +const reorderReducer = (state: ReorderState, action: ReorderAction) => { + switch (action.type) { + case 'reset': + return { ...state, reorderedItems: [] }; + case 'registerDraggingItemHeight': + return { ...state, draggingHeight: action.payload }; + case 'registerReorderedItemHeight': + return { + ...state, + reorderedItems: state.reorderedItems.map((i) => + i.id === action.payload.id ? { ...i, height: action.payload.height } : i + ), + }; + case 'setIsReorderOn': + return { ...state, isReorderOn: action.payload }; + case 'setReorderedItems': + const { items, draggingIndex, droppingIndex } = action.payload; + return draggingIndex < droppingIndex + ? { + ...state, + reorderedItems: items.slice(draggingIndex + 1, droppingIndex + 1), + direction: '-' as const, + } + : { + ...state, + reorderedItems: items.slice(droppingIndex, draggingIndex), + direction: '+' as const, + }; + default: + return state; + } +}; + export function ReorderProvider({ - id, children, className, - draggingHeight = REORDER_ITEM_HEIGHT, dataTestSubj = DEFAULT_DATA_TEST_SUBJ, }: { - id: string; children: React.ReactNode; className?: string; - draggingHeight?: number; dataTestSubj?: string; }) { - const [state, setState] = useState({ - reorderedItems: [], - direction: '-', - draggingHeight, - isReorderOn: false, - groupId: id, - }); - - const setReorderState = useMemo( - () => (dispatch: SetReorderStateDispatch) => setState(dispatch), - [setState] + const [state, dispatch] = useReducer>( + reorderReducer, + initialState ); return ( @@ -103,9 +150,7 @@ export function ReorderProvider({ 'domDragDrop-isActiveGroup': state.isReorderOn && React.Children.count(children) > 1, })} > - - {children} - + {children}

); } diff --git a/packages/kbn-dom-drag-drop/src/providers/types.tsx b/packages/kbn-dom-drag-drop/src/providers/types.tsx index 3c1523cb15e9b..e0a460569a70f 100644 --- a/packages/kbn-dom-drag-drop/src/providers/types.tsx +++ b/packages/kbn-dom-drag-drop/src/providers/types.tsx @@ -7,6 +7,7 @@ */ import { DropType } from '../types'; +import { DragDropAction } from './providers'; export interface HumanData { label: string; @@ -57,45 +58,34 @@ export type DropHandler = (dropped: DragDropIdentifier, dropType?: DropType) => export type RegisteredDropTargets = Record | undefined; -/** - * The shape of the drag / drop context. - */ export interface DragContextState { /** * The item being dragged or undefined. */ dragging?: DraggingIdentifier; - /** * keyboard mode */ keyboardMode: boolean; /** - * keyboard mode + * currently selected drop target */ - setKeyboardMode: (mode: boolean) => void; + activeDropTarget?: DropIdentifier; /** - * Set the item being dragged. + * currently registered drop targets */ - setDragging: (dragging?: DraggingIdentifier) => void; - - activeDropTarget?: DropIdentifier; - dropTargetsByOrder: RegisteredDropTargets; - setActiveDropTarget: (newTarget?: DropIdentifier) => void; - - setA11yMessage: (message: string) => void; - registerDropTarget: (order: number[], dropTarget?: DropIdentifier) => void; - /** * Customizable data-test-subj prefix */ dataTestSubjPrefix: string; - - /** - * A custom callback for telemetry - * @param event - */ - onTrackUICounterEvent?: (event: string) => void; } + +export type CustomMiddleware = (action: DragDropAction) => void; + +export type DragContextValue = [ + state: DragContextState, + dispatch: React.Dispatch, + customMiddleware?: CustomMiddleware +]; diff --git a/packages/kbn-unified-field-list/src/components/field_item_button/field_item_button.tsx b/packages/kbn-unified-field-list/src/components/field_item_button/field_item_button.tsx index 086db539487ec..13860a0e4f155 100644 --- a/packages/kbn-unified-field-list/src/components/field_item_button/field_item_button.tsx +++ b/packages/kbn-unified-field-list/src/components/field_item_button/field_item_button.tsx @@ -62,6 +62,7 @@ export interface FieldItemButtonProps { * @param otherProps * @constructor */ + export function FieldItemButton({ field, fieldSearchHighlight, diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx index b31feed5813fe..de51aa80c92d4 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ import './discover_layout.scss'; -import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { EuiButtonIcon, EuiFlexGroup, @@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n'; import { METRIC_TYPE } from '@kbn/analytics'; import classNames from 'classnames'; import { generateFilters } from '@kbn/data-plugin/public'; -import { DragContext } from '@kbn/dom-drag-drop'; +import { useDragDropContext } from '@kbn/dom-drag-drop'; import { DataViewField, DataViewType } from '@kbn/data-views-plugin/public'; import { useSavedSearchInitial } from '../../services/discover_state_provider'; import { DiscoverStateContainer } from '../../services/discover_state'; @@ -182,8 +182,8 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) { const resizeRef = useRef(null); - const dragDropContext = useContext(DragContext); - const draggingFieldName = dragDropContext.dragging?.id; + const [{ dragging }] = useDragDropContext(); + const draggingFieldName = dragging?.id; const onDropFieldToTable = useMemo(() => { if (!draggingFieldName || currentColumns.includes(draggingFieldName)) { diff --git a/src/plugins/event_annotation/public/components/group_editor_controls/annotation_list.tsx b/src/plugins/event_annotation/public/components/group_editor_controls/annotation_list.tsx index f29638e202548..c81552100ccc6 100644 --- a/src/plugins/event_annotation/public/components/group_editor_controls/annotation_list.tsx +++ b/src/plugins/event_annotation/public/components/group_editor_controls/annotation_list.tsx @@ -7,13 +7,18 @@ */ import { css } from '@emotion/react'; -import { DragContext, DragDrop, DropTargetSwapDuplicateCombine } from '@kbn/dom-drag-drop'; +import { + DragDrop, + DropTargetSwapDuplicateCombine, + ReorderProvider, + useDragDropContext, +} from '@kbn/dom-drag-drop'; import { DimensionButton, DimensionTrigger, EmptyDimensionButton, } from '@kbn/visualization-ui-components/public'; -import React, { useCallback, useContext, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { euiThemeVars } from '@kbn/ui-theme'; import { i18n } from '@kbn/i18n'; @@ -34,8 +39,6 @@ export const AnnotationList = ({ setNewAnnotationId(uuidv4()); }, [annotations.length]); - const { dragging } = useContext(DragContext); - const addAnnotationText = i18n.translate('eventAnnotation.annotationList.add', { defaultMessage: 'Add annotation', }); @@ -59,45 +62,78 @@ export const AnnotationList = ({ [annotations, newAnnotationId, selectAnnotation, updateAnnotations] ); + const reorderAnnotations = useCallback( + ( + sourceAnnotation: EventAnnotationConfig | undefined, + targetAnnotation: EventAnnotationConfig + ) => { + if (!sourceAnnotation || sourceAnnotation.id === targetAnnotation.id) { + return annotations; + } + const newAnnotations = annotations.filter((c) => c.id !== sourceAnnotation.id); + const targetPosition = newAnnotations.findIndex((c) => c.id === targetAnnotation.id); + const targetIndex = annotations.indexOf(sourceAnnotation); + const sourceIndex = annotations.indexOf(targetAnnotation); + newAnnotations.splice( + targetIndex < sourceIndex ? targetPosition + 1 : targetPosition, + 0, + sourceAnnotation + ); + return updateAnnotations(newAnnotations); + }, + [annotations, updateAnnotations] + ); + + const [{ dragging }] = useDragDropContext(); + return (
- {annotations.map((annotation, index) => ( -
- + {annotations.map((annotation, index) => ( +
- selectAnnotation(annotation)} - onRemoveClick={() => - updateAnnotations(annotations.filter(({ id }) => id !== annotation.id)) - } - accessorConfig={getAnnotationAccessor(annotation)} - label={annotation.label} + { + const sourceAnnotation = source + ? annotations.find(({ id }) => id === source.id) + : undefined; + reorderAnnotations(sourceAnnotation, annotation); + }} > - - - -
- ))} + selectAnnotation(annotation)} + onRemoveClick={() => + updateAnnotations(annotations.filter(({ id }) => id !== annotation.id)) + } + accessorConfig={getAnnotationAccessor(annotation)} + label={annotation.label} + > + + +
+
+ ))} +
{ fieldFormats: fieldFormatsServiceMock.createStartContract(), indexPatternFieldEditor: indexPatternFieldEditorPluginMock.createStartContract(), onIndexPatternRefresh: jest.fn(), - dragDropContext: createMockedDragDropContext(), currentIndexPatternId: '1', core, dateRange: { @@ -387,10 +386,6 @@ describe('FormBased Data Panel', () => { currentIndexPatternId: '', }} setState={jest.fn()} - dragDropContext={{ - ...createMockedDragDropContext(), - dragging: { id: '1', humanData: { label: 'Label' } }, - }} frame={createMockFramePublicAPI()} /> ); @@ -413,10 +408,9 @@ describe('FormBased Data Panel', () => { dataViews, }), setState: jest.fn(), - dragDropContext: { - ...createMockedDragDropContext(), + dragDropContext: createMockedDragDropContext({ dragging: { id: '1', humanData: { label: 'Label' } }, - }, + }), dateRange: { fromDate: '2019-01-01', toDate: '2020-01-01' }, frame: getFrameAPIMock({ indexPatterns: indexPatterns as unknown as DataViewsState['indexPatterns'], diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx index 3fddb3bedd9a9..82758d83b56c9 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx @@ -27,7 +27,6 @@ import { useExistingFieldsFetcher, useGroupedFields, } from '@kbn/unified-field-list'; -import { ChildDragDropProvider, DragContextState } from '@kbn/dom-drag-drop'; import { ChartsPluginSetup } from '@kbn/charts-plugin/public'; import type { DatasourceDataPanelProps, @@ -41,7 +40,7 @@ import { FieldItem } from '../common/field_item'; export type Props = Omit< DatasourceDataPanelProps, - 'core' | 'onChangeIndexPattern' + 'core' | 'onChangeIndexPattern' | 'dragDropContext' > & { data: DataPublicPluginStart; dataViews: DataViewsPublicPluginStart; @@ -77,7 +76,6 @@ function onSupportedFieldFilter(field: IndexPatternField): boolean { export function FormBasedDataPanel({ state, - dragDropContext, core, data, dataViews, @@ -144,7 +142,6 @@ export function FormBasedDataPanel({ query={query} dateRange={dateRange} filters={filters} - dragDropContext={dragDropContext} core={core} data={data} dataViews={dataViews} @@ -171,7 +168,6 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({ query, dateRange, filters, - dragDropContext, core, data, dataViews, @@ -187,14 +183,13 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({ activeIndexPatterns, }: Omit< DatasourceDataPanelProps, - 'state' | 'setState' | 'core' | 'onChangeIndexPattern' | 'usedIndexPatterns' + 'state' | 'setState' | 'core' | 'onChangeIndexPattern' | 'usedIndexPatterns' | 'dragDropContext' > & { data: DataPublicPluginStart; dataViews: DataViewsPublicPluginStart; fieldFormats: FieldFormatsStart; core: CoreStart; currentIndexPatternId: string; - dragDropContext: DragContextState; charts: ChartsPluginSetup; frame: FramePublicAPI; indexPatternFieldEditor: IndexPatternFieldEditorStart; @@ -398,20 +393,18 @@ export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({ ); return ( - - } - > - - {...fieldListGroupedProps} - renderFieldItem={renderFieldItem} - data-test-subj="lnsIndexPattern" - localStorageKeyPrefix="lens" - /> - - + } + > + + {...fieldListGroupedProps} + renderFieldItem={renderFieldItem} + data-test-subj="lnsIndexPattern" + localStorageKeyPrefix="lens" + /> + ); }; diff --git a/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx index f650fe36b4426..533cdb179f64a 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx @@ -25,8 +25,9 @@ import { FormattedMessage } from '@kbn/i18n-react'; import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { EuiButton } from '@elastic/eui'; import type { SharePluginStart } from '@kbn/share-plugin/public'; -import type { DraggingIdentifier } from '@kbn/dom-drag-drop'; +import { ChildDragDropProvider, type DraggingIdentifier } from '@kbn/dom-drag-drop'; import { DimensionTrigger } from '@kbn/visualization-ui-components/public'; +import memoizeOne from 'memoize-one'; import type { DatasourceDimensionEditorProps, DatasourceDimensionTriggerProps, @@ -72,7 +73,7 @@ import { cloneLayer, getNotifiableFeatures, } from './utils'; -import { getUniqueLabelGenerator, isDraggedDataViewField } from '../../utils'; +import { getUniqueLabelGenerator, isDraggedDataViewField, nonNullable } from '../../utils'; import { hasField, normalizeOperationDataType } from './pure_utils'; import { LayerPanel } from './layerpanel'; import { @@ -112,6 +113,20 @@ function wrapOnDot(str?: string) { return str ? str.replace(/\./g, '.\u200B') : ''; } +const getSelectedFieldsFromColumns = memoizeOne( + (columns: GenericIndexPatternColumn[]) => + columns + .flatMap((c) => { + if (operationDefinitionMap[c.operationType]?.getCurrentFields) { + return operationDefinitionMap[c.operationType]?.getCurrentFields?.(c) || []; + } else if ('sourceField' in c) { + return c.sourceField; + } + }) + .filter(nonNullable), + isEqual +); + function getSortingHint(column: GenericIndexPatternColumn, dataView?: IndexPattern | DataView) { if (column.dataType === 'string') { const fieldTypes = @@ -421,18 +436,9 @@ export function getFormBasedDatasource({ }, getSelectedFields(state) { - const fields: string[] = []; - Object.values(state?.layers)?.forEach((l) => { - const { columns } = l; - Object.values(columns).forEach((c) => { - if (operationDefinitionMap[c.operationType]?.getCurrentFields) { - fields.push(...(operationDefinitionMap[c.operationType]?.getCurrentFields?.(c) || [])); - } else if ('sourceField' in c) { - fields.push(c.sourceField); - } - }); - }); - return fields; + return getSelectedFieldsFromColumns( + Object.values(state?.layers)?.flatMap((l) => Object.values(l.columns)) + ); }, toExpression: (state, layerId, indexPatterns, dateRange, nowInstant, searchSessionId) => @@ -470,7 +476,7 @@ export function getFormBasedDatasource({ }, renderDataPanel(domElement: Element, props: DatasourceDataPanelProps) { - const { onChangeIndexPattern, ...otherProps } = props; + const { onChangeIndexPattern, dragDropContext, ...otherProps } = props; const layerFields = formBasedDatasource?.getSelectedFields?.(props.state); render( @@ -487,18 +493,20 @@ export function getFormBasedDatasource({ share, }} > - + + + , diff --git a/x-pack/plugins/lens/public/datasources/form_based/mocks.ts b/x-pack/plugins/lens/public/datasources/form_based/mocks.ts index c148ebc9f9829..c01495f1993e4 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/mocks.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/mocks.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { DragContextState } from '@kbn/dom-drag-drop'; import { getFieldByNameFactory } from './pure_helpers'; import type { IndexPattern, IndexPatternField } from '../../types'; @@ -217,18 +216,3 @@ export const createMockedIndexPatternWithoutType = ( getFieldByName: getFieldByNameFactory(filteredFields), }; }; - -export function createMockedDragDropContext(): jest.Mocked { - return { - dataTestSubjPrefix: 'lnsDragDrop', - dragging: undefined, - setDragging: jest.fn(), - activeDropTarget: undefined, - setActiveDropTarget: jest.fn(), - keyboardMode: false, - setKeyboardMode: jest.fn(), - setA11yMessage: jest.fn(), - dropTargetsByOrder: undefined, - registerDropTarget: jest.fn(), - }; -} diff --git a/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx index abc84813ce9a2..210678fa909f3 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx @@ -28,8 +28,7 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { createIndexPatternServiceMock } from '../../mocks/data_views_service_mock'; -import { createMockFramePublicAPI } from '../../mocks'; -import { createMockedDragDropContext } from './mocks'; +import { createMockFramePublicAPI, createMockedDragDropContext } from '../../mocks'; import { DataViewsState } from '../../state_management'; const fieldsFromQuery = [ diff --git a/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx index 1a5bfeaa41be9..8477b94d951bf 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx @@ -24,7 +24,6 @@ import { GetCustomFieldType, useGroupedFields, } from '@kbn/unified-field-list'; -import { ChildDragDropProvider } from '@kbn/dom-drag-drop'; import type { DatasourceDataPanelProps } from '../../types'; import type { TextBasedPrivateState } from './types'; import { getStateFromAggregateQuery } from './utils'; @@ -42,7 +41,6 @@ export type TextBasedDataPanelProps = DatasourceDataPanelProps) { const prevQuery = usePrevious(query); const [dataHasLoaded, setDataHasLoaded] = useState(false); useEffect(() => { @@ -138,22 +136,20 @@ export function TextBasedDataPanel({ ...core, }} > - - - } - > - - {...fieldListGroupedProps} - renderFieldItem={renderFieldItem} - data-test-subj="lnsTextBasedLanguages" - localStorageKeyPrefix="lens" - /> - - + + } + > + + {...fieldListGroupedProps} + renderFieldItem={renderFieldItem} + data-test-subj="lnsTextBasedLanguages" + localStorageKeyPrefix="lens" + /> + ); } diff --git a/x-pack/plugins/lens/public/datasources/text_based/mocks.ts b/x-pack/plugins/lens/public/datasources/text_based/mocks.ts deleted file mode 100644 index 870b43c7b0a84..0000000000000 --- a/x-pack/plugins/lens/public/datasources/text_based/mocks.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { DragContextState } from '@kbn/dom-drag-drop'; - -export function createMockedDragDropContext(): jest.Mocked { - return { - dataTestSubjPrefix: 'lnsDragDrop', - dragging: undefined, - setDragging: jest.fn(), - activeDropTarget: undefined, - setActiveDropTarget: jest.fn(), - keyboardMode: false, - setKeyboardMode: jest.fn(), - setA11yMessage: jest.fn(), - dropTargetsByOrder: undefined, - registerDropTarget: jest.fn(), - }; -} diff --git a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx index 653a3f30e1b44..f93efd9835ee2 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx @@ -20,6 +20,9 @@ import type { DataViewsPublicPluginStart, DataView } from '@kbn/data-views-plugi import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { euiThemeVars } from '@kbn/ui-theme'; import { DimensionTrigger } from '@kbn/visualization-ui-components/public'; +import memoizeOne from 'memoize-one'; +import { isEqual } from 'lodash'; +import { ChildDragDropProvider } from '@kbn/dom-drag-drop'; import { DatasourceDimensionEditorProps, DatasourceDataPanelProps, @@ -43,12 +46,24 @@ import type { import { FieldSelect } from './field_select'; import type { Datasource, IndexPatternMap } from '../../types'; import { LayerPanel } from './layerpanel'; -import { getUniqueLabelGenerator } from '../../utils'; +import { getUniqueLabelGenerator, nonNullable } from '../../utils'; function getLayerReferenceName(layerId: string) { return `textBasedLanguages-datasource-layer-${layerId}`; } +const getSelectedFieldsFromColumns = memoizeOne( + (columns: TextBasedLayerColumn[]) => + columns + .map((c) => { + if ('fieldName' in c) { + return c.fieldName; + } + }) + .filter(nonNullable), + isEqual +); + export function getTextBasedDatasource({ core, storage, @@ -344,30 +359,26 @@ export function getTextBasedDatasource({ return toExpression(state, layerId); }, getSelectedFields(state) { - const fields: string[] = []; - Object.values(state?.layers)?.forEach((l) => { - const { columns } = l; - Object.values(columns).forEach((c) => { - if ('fieldName' in c) { - fields.push(c.fieldName); - } - }); - }); - return fields; + return getSelectedFieldsFromColumns( + Object.values(state?.layers)?.flatMap((l) => Object.values(l.columns)) + ); }, renderDataPanel(domElement: Element, props: DatasourceDataPanelProps) { const layerFields = TextBasedDatasource?.getSelectedFields?.(props.state); + const { dragDropContext, ...otherProps } = props; render( - + + + , domElement diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/draggable_dimension_button.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/draggable_dimension_button.tsx index 910f97fb446e3..ae226521799eb 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/draggable_dimension_button.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/draggable_dimension_button.tsx @@ -5,11 +5,11 @@ * 2.0. */ -import React, { useMemo, useCallback, useContext, ReactElement } from 'react'; +import React, { useMemo, useCallback, ReactElement } from 'react'; import { DragDrop, DragDropIdentifier, - DragContext, + useDragDropContext, DropType, DropTargetSwapDuplicateCombine, } from '@kbn/dom-drag-drop'; @@ -61,7 +61,7 @@ export function DraggableDimensionButton({ registerNewButtonRef: (id: string, instance: HTMLDivElement | null) => void; indexPatterns: IndexPatternMap; }) { - const { dragging } = useContext(DragContext); + const [{ dragging }] = useDragDropContext(); let getDropProps; @@ -139,20 +139,20 @@ export function DraggableDimensionButton({ data-test-subj={group.dataTestSubj} > 1 ? reorderableGroup : undefined} value={value} onDrop={handleOnDrop} - onDragStart={() => onDragStart()} - onDragEnd={() => onDragEnd()} + onDragStart={onDragStart} + onDragEnd={onDragEnd} > {children} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/empty_dimension_button.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/empty_dimension_button.tsx index 1e2b3ff4b4c05..051ba4876eb35 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/empty_dimension_button.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/buttons/empty_dimension_button.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import React, { useMemo, useState, useEffect, useContext } from 'react'; +import React, { useMemo, useState, useEffect } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { DragDrop, DragDropIdentifier, - DragContext, + useDragDropContext, DropType, DropTargetSwapDuplicateCombine, } from '@kbn/dom-drag-drop'; @@ -116,7 +116,7 @@ export function EmptyDimensionButton({ }; }; }) { - const { dragging } = useContext(DragContext); + const [{ dragging }] = useDragDropContext(); let getDropProps; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx index 1555445d482d8..9db931efeda26 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx @@ -20,6 +20,7 @@ import { createMockDatasource, DatasourceMock, mountWithProvider, + createMockedDragDropContext, } from '../../../mocks'; import { createIndexPatternServiceMock } from '../../../mocks/data_views_service_mock'; import { DimensionButton } from '@kbn/visualization-ui-components/public'; @@ -52,19 +53,6 @@ afterEach(() => { container = undefined; }); -const defaultContext = { - dataTestSubjPrefix: 'lnsDragDrop', - dragging: undefined, - setDragging: jest.fn(), - setActiveDropTarget: () => {}, - activeDropTarget: undefined, - dropTargetsByOrder: undefined, - keyboardMode: false, - setKeyboardMode: () => {}, - setA11yMessage: jest.fn(), - registerDropTarget: jest.fn(), -}; - const draggingField = { field: { name: 'dragged' }, indexPatternId: 'a', @@ -773,7 +761,7 @@ describe('LayerPanel', () => { }); const { instance } = await mountWithProvider( - + ); @@ -817,7 +805,7 @@ describe('LayerPanel', () => { ); const { instance } = await mountWithProvider( - + ); @@ -886,7 +874,7 @@ describe('LayerPanel', () => { }; const { instance } = await mountWithProvider( - + ); @@ -956,7 +944,7 @@ describe('LayerPanel', () => { }; const { instance } = await mountWithProvider( - + , undefined, @@ -1009,7 +997,7 @@ describe('LayerPanel', () => { }; const { instance } = await mountWithProvider( - + ); @@ -1064,7 +1052,7 @@ describe('LayerPanel', () => { const mockOnRemoveDimension = jest.fn(); const { instance } = await mountWithProvider( - + { const mockOnRemoveDimension = jest.fn(); const { instance } = await mountWithProvider( - + { const mockOnRemoveDimension = jest.fn(); const { instance } = await mountWithProvider( - + { const mockOnRemoveDimension = jest.fn(); const { instance } = await mountWithProvider( - + <> {group.accessors.length ? ( - + {group.accessors.map((accessorConfig, accessorIndex) => { const { columnId } = accessorConfig; @@ -644,7 +640,6 @@ export function LayerPanel( {group.fakeFinalAccessor && (
arg, isEqual); + export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => { const externalContext = useLensSelector(selectExecutionContext); const activeDatasourceId = useLensSelector(selectActiveDatasourceId); @@ -158,7 +162,7 @@ export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => { const datasourceProps: DatasourceDataPanelProps = { ...externalContext, - dragDropContext: useContext(DragContext), + dragDropContext: useDragDropContext(), state: activeDatasourceId ? datasourceStates[activeDatasourceId].state : null, setState: setDatasourceState, core: props.core, @@ -170,7 +174,7 @@ export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => { indexPatternService: props.indexPatternService, frame: props.frame, // Visualization can handle dataViews, so need to pass to the data panel the full list of used dataViews - usedIndexPatterns: [ + usedIndexPatterns: memoizeStrictlyEqual([ ...((activeDatasourceId && props.datasourceMap[activeDatasourceId]?.getUsedDataViews( datasourceStates[activeDatasourceId].state @@ -181,7 +185,7 @@ export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => { visualizationState.state )) || []), - ], + ]), }; return ( diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx index 01ac257dbcb2d..8571b2ca347b0 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx @@ -820,11 +820,16 @@ describe('editor_frame', () => { getDatasourceSuggestionsForField: () => [generateSuggestion()], getDatasourceSuggestionsFromCurrentState: () => [generateSuggestion()], getDatasourceSuggestionsForVisualizeField: () => [generateSuggestion()], - renderDataPanel: (_element, { dragDropContext: { setDragging, dragging } }) => { + renderDataPanel: (_element, { dragDropContext: [{ dragging }, dndDispatch] }) => { if (!dragging || dragging.id !== 'draggedField') { - setDragging({ - id: 'draggedField', - humanData: { label: 'draggedField' }, + dndDispatch({ + type: 'startDragging', + payload: { + dragging: { + id: 'draggedField', + humanData: { label: 'draggedField' }, + }, + }, }); } }, @@ -922,11 +927,16 @@ describe('editor_frame', () => { getDatasourceSuggestionsForField: () => [generateSuggestion()], getDatasourceSuggestionsFromCurrentState: () => [generateSuggestion()], getDatasourceSuggestionsForVisualizeField: () => [generateSuggestion()], - renderDataPanel: (_element, { dragDropContext: { setDragging, dragging } }) => { + renderDataPanel: (_element, { dragDropContext: [{ dragging }, dndDispatch] }) => { if (!dragging || dragging.id !== 'draggedField') { - setDragging({ - id: 'draggedField', - humanData: { label: '1' }, + dndDispatch({ + type: 'startDragging', + payload: { + dragging: { + id: 'draggedField', + humanData: { label: '1' }, + }, + }, }); } }, diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx index a7e1e1449ad2f..24d0d3bba780c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx @@ -8,7 +8,7 @@ import React, { useCallback, useRef } from 'react'; import { CoreStart } from '@kbn/core/public'; import { ReactExpressionRendererType } from '@kbn/expressions-plugin/public'; -import { DragDropIdentifier, RootDragDropProvider } from '@kbn/dom-drag-drop'; +import { type DragDropAction, DragDropIdentifier, RootDragDropProvider } from '@kbn/dom-drag-drop'; import { trackUiCounterEvents } from '../../lens_ui_telemetry'; import { DatasourceMap, @@ -108,8 +108,14 @@ export function EditorFrame(props: EditorFrameProps) { const bannerMessages = props.getUserMessages('banner', { severity: 'warning' }); + const telemetryMiddleware = useCallback((action: DragDropAction) => { + if (action.type === 'dropToTarget') { + trackUiCounterEvents('drop_total'); + } + }, []); + return ( - + { @@ -934,18 +935,7 @@ describe('workspace_panel', () => { async function initComponent(draggingContext = draggedField) { const mounted = await mountWithProvider( - {}} - setActiveDropTarget={() => {}} - activeDropTarget={undefined} - keyboardMode={false} - setKeyboardMode={() => {}} - setA11yMessage={() => {}} - registerDropTarget={jest.fn()} - dropTargetsByOrder={undefined} - > + dragDropContext.dragging && getSuggestionForField(dragDropContext.dragging), - [dragDropContext.dragging, getSuggestionForField] + () => dragging && getSuggestionForField(dragging), + [dragging, getSuggestionForField] ); return ( @@ -573,15 +573,15 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ ); }; - const dragDropContext = useContext(DragContext); + const [{ dragging }] = useDragDropContext(); const renderWorkspace = () => { const customWorkspaceRenderer = activeDatasourceId && datasourceMap[activeDatasourceId]?.getCustomWorkspaceRenderer && - dragDropContext.dragging + dragging ? datasourceMap[activeDatasourceId].getCustomWorkspaceRenderer!( datasourceStates[activeDatasourceId].state, - dragDropContext.dragging, + dragging, dataViews.indexPatterns ) : undefined; diff --git a/x-pack/plugins/lens/public/mocks/index.ts b/x-pack/plugins/lens/public/mocks/index.ts index 5cd62b5427cb4..c71da33fda3c9 100644 --- a/x-pack/plugins/lens/public/mocks/index.ts +++ b/x-pack/plugins/lens/public/mocks/index.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { DragContextState, DragContextValue } from '@kbn/dom-drag-drop'; import { createMockDataViewsState } from '../data_views_service/mocks'; import { FramePublicAPI, FrameDatasourceAPI } from '../types'; export { mockDataPlugin } from './data_plugin_mock'; @@ -65,3 +66,20 @@ export const createMockFrameDatasourceAPI = ({ filters: filters ?? [], dataViews: createMockDataViewsState(dataViews), }); + +export function createMockedDragDropContext( + partialState?: Partial, + setState?: jest.Mocked[1] +): jest.Mocked { + return [ + { + dataTestSubjPrefix: 'lnsDragDrop', + dragging: undefined, + keyboardMode: false, + activeDropTarget: undefined, + dropTargetsByOrder: undefined, + ...partialState, + }, + setState ? setState : jest.fn(), + ]; +} diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 607b46f9e98f2..042bdef118984 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -43,7 +43,7 @@ import { EventAnnotationGroupConfig } from '@kbn/event-annotation-plugin/common' import type { DraggingIdentifier, DragDropIdentifier, - DragContextState, + DragContextValue, DropType, } from '@kbn/dom-drag-drop'; import type { AccessorConfig } from '@kbn/visualization-ui-components/public'; @@ -588,7 +588,7 @@ export interface DatasourceLayerSettingsProps { export interface DatasourceDataPanelProps { state: T; - dragDropContext: DragContextState; + dragDropContext: DragContextValue; setState: StateSetter; showNoDataPopover: () => void; core: Pick< From f8ef18a26bd4f07bd7ad7a7e59ed83f4204cd813 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 11 Jul 2023 14:32:33 +0300 Subject: [PATCH 09/97] [Textbased] Depict histogram for timebased adhoc dataviews (#161524) ## Summary Part of https://github.com/elastic/kibana/issues/158802 We decided that in the case we don't render a Lens suggestion (for example when we have the SELECT * case) to render the histogram. **Reminder**: Histogram makes sense only of there is a time field. For text based mode, time field exists **ONLY** if there is the @timestamp field. I don't allow navigation to Lens or open the edit flyout in this case. When the edit flyout allows the editing of the form based visualizations (such as histogram) I will enable it then. FTs have been changed to accomodate this change. image ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../unified_histogram/public/chart/chart.test.tsx | 11 +++++++++++ .../unified_histogram/public/chart/chart.tsx | 3 ++- .../public/chart/histogram.test.tsx | 1 + .../unified_histogram/public/chart/histogram.tsx | 9 ++++++--- .../public/layout/hooks/use_lens_suggestions.ts | 2 +- test/functional/apps/discover/group2/_sql_view.ts | 4 ++-- .../tests/apps/discover/async_search.ts | 13 ------------- 7 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/plugins/unified_histogram/public/chart/chart.test.tsx b/src/plugins/unified_histogram/public/chart/chart.test.tsx index b32979cc004e5..640ca91c0bc89 100644 --- a/src/plugins/unified_histogram/public/chart/chart.test.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.test.tsx @@ -244,6 +244,17 @@ describe('Chart', () => { ).toBeTruthy(); }); + it('should not render the edit on the fly button when chart is visible and suggestions dont exist', async () => { + const component = await mountComponent({ + currentSuggestion: undefined, + allSuggestions: undefined, + isPlainRecord: true, + }); + expect( + component.find('[data-test-subj="unifiedHistogramEditFlyoutVisualization"]').exists() + ).toBeFalsy(); + }); + it('should render the save button when chart is visible and suggestions exist', async () => { const component = await mountComponent({ currentSuggestion: currentSuggestionMock, diff --git a/src/plugins/unified_histogram/public/chart/chart.tsx b/src/plugins/unified_histogram/public/chart/chart.tsx index 6b112f3578df9..907ec70aa3b69 100644 --- a/src/plugins/unified_histogram/public/chart/chart.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.tsx @@ -275,7 +275,7 @@ export function Chart({ [isFlyoutVisible] ); - const canEditVisualizationOnTheFly = isPlainRecord && chartVisible; + const canEditVisualizationOnTheFly = currentSuggestion && chartVisible; return ( TimeRange; refetch$: Observable; lensAttributesContext: LensAttributesContext; @@ -58,6 +59,7 @@ export function Histogram({ hits, chart: { timeInterval }, isPlainRecord, + hasLensSuggestions, getTimeRange, refetch$, lensAttributesContext: attributesContext, @@ -109,9 +111,10 @@ export function Histogram({ } const adapterTables = adapters?.tables?.tables; - const totalHits = isPlainRecord - ? Object.values(adapterTables ?? {})?.[0]?.rows?.length - : adapterTables?.unifiedHistogram?.meta?.statistics?.totalCount; + const totalHits = + isPlainRecord && hasLensSuggestions + ? Object.values(adapterTables ?? {})?.[0]?.rows?.length + : adapterTables?.unifiedHistogram?.meta?.statistics?.totalCount; onTotalHitsChange?.( isLoading ? UnifiedHistogramFetchStatus.loading : UnifiedHistogramFetchStatus.complete, diff --git a/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts b/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts index c94767eb67842..a8a90faa18a9a 100644 --- a/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts +++ b/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts @@ -69,7 +69,7 @@ export const useLensSuggestions = ({ return { allSuggestions, currentSuggestion, - suggestionUnsupported: isPlainRecord && !currentSuggestion, + suggestionUnsupported: !dataView.isTimeBased(), }; }; diff --git a/test/functional/apps/discover/group2/_sql_view.ts b/test/functional/apps/discover/group2/_sql_view.ts index 6374ee405c70a..95ce1516728d2 100644 --- a/test/functional/apps/discover/group2/_sql_view.ts +++ b/test/functional/apps/discover/group2/_sql_view.ts @@ -72,8 +72,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await testSubjects.exists('showQueryBarMenu')).to.be(false); expect(await testSubjects.exists('addFilter')).to.be(false); expect(await testSubjects.exists('dscViewModeDocumentButton')).to.be(false); - // here Lens suggests a table so the chart is not rendered - expect(await testSubjects.exists('unifiedHistogramChart')).to.be(false); + // when Lens suggests a table, we render the histogram + expect(await testSubjects.exists('unifiedHistogramChart')).to.be(true); expect(await testSubjects.exists('unifiedHistogramQueryHits')).to.be(true); expect(await testSubjects.exists('discoverAlertsButton')).to.be(false); expect(await testSubjects.exists('shareTopNavButton')).to.be(true); diff --git a/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts b/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts index 021aab2212165..ddbd07ef0c10e 100644 --- a/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts +++ b/x-pack/test/search_sessions_integration/tests/apps/discover/async_search.ts @@ -131,19 +131,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(searchesCountBeforeRestore).to.be(searchesCountAfterRestore); // no new searches started during restore }); - - it('should should clean the search session when navigating to SQL mode, and reinitialize when navigating back', async () => { - await PageObjects.common.navigateToApp('discover'); - await PageObjects.timePicker.setDefaultAbsoluteRange(); - await PageObjects.header.waitUntilLoadingHasFinished(); - expect(await searchSessions.exists()).to.be(true); - await PageObjects.discover.selectTextBaseLang('SQL'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await searchSessions.missingOrFail(); - await browser.goBack(); - await PageObjects.header.waitUntilLoadingHasFinished(); - expect(await searchSessions.exists()).to.be(true); - }); }); async function getSearchSessionId(): Promise { From 5d066944fcef558eacc858bb807acb2fb783eaee Mon Sep 17 00:00:00 2001 From: Ashokaditya <1849116+ashokaditya@users.noreply.github.com> Date: Tue, 11 Jul 2023 13:58:42 +0200 Subject: [PATCH 10/97] [Defend Workflows] Unskip policy response test (#161588) ## Summary Unskip test that was timing out at indexing test hosts. The timeout has since been increased in elastic/kibana/pull/159518 Was added in elastic/kibana/pull/154505 and skipped in elastic/kibana/pull/156104 --- .../management/cypress/e2e/mocked_data/policy_response.cy.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/policy_response.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/policy_response.cy.ts index 63d9f26514ba5..3100d4a64fec7 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/policy_response.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/policy_response.cy.ts @@ -15,8 +15,7 @@ import { navigateToFleetAgentDetails } from '../../screens/fleet'; import { EndpointPolicyResponseGenerator } from '../../../../../common/endpoint/data_generators/endpoint_policy_response_generator'; import { descriptions } from '../../../components/policy_response/policy_response_friendly_names'; -// FLAKY: https://github.com/elastic/security-team/issues/6518 -describe.skip('Endpoint Policy Response', () => { +describe('Endpoint Policy Response', () => { let loadedEndpoint: CyIndexEndpointHosts; let endpointMetadata: HostMetadata; let loadedPolicyResponse: IndexedEndpointPolicyResponse; From 95e50875e1139d3cd16b53ad9c9245369ac59284 Mon Sep 17 00:00:00 2001 From: Marta Bondyra <4283304+mbondyra@users.noreply.github.com> Date: Tue, 11 Jul 2023 14:05:45 +0200 Subject: [PATCH 11/97] [Lens] Remove (#161521) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary The NativeRenderer component is currently used to mount another component in a separate mounting point. As far as I recall, we introduced to allow users to create visualizations in non-React frameworks. The idea was that users could write their own Lens visualizations or datasources code and integrate it with our system. However, it seems that this concept hasn't gained traction and we don’t have it prioritized. Even if users express interest in writing their visualizations outside of React, it is still possible to do so with some additional boilerplate code (which we could provide as an example non-React visualization). Pros: 1. Simplifies and shortens the code: 1.1. Testing and debugging become easier as we no longer need to check separate React trees when integrating frame, data source, and visualization components. 1.2. Components communicate using standard React patterns, making maintenance and comprehension simpler. 1.3. Context providers no longer need to be passed to each separate component since they are already within the context. 1.4. Easier propagation of events or any other form of inter-component communication. 2. Greatly improves performance and facilitates maintenance: 2.1. Directly accessing context inside the DatasourcePanel eliminates the need for context passing, resulting in better performance. 2.2. Removing the requirement for a separate React root also contributes to improved performance. 3. The render method will be removed when we upgrade to React 18. While we could replace it with the new createRoot method, it makes sense to perform some cleanup ;) Cons: 1. Setting up non-React visualization or data source code might become slightly more complex. Performance improvement for drag and drop action with these changes: before: Screenshot 2023-07-10 at 07 14 39 after: Screenshot 2023-07-10 at 07 16 24 ## Single render when dragging: (the first image is 3 screenshots from 3 different react roots as they have separate mounting point. The complete render time is ~380ms) Screenshot 2023-07-10 at 07 16 24 After we have one common render tree. Because we don't have to pass context down as a prop, we greatly reduced the number of components rerendered. (I will be working on reducing the render time for workspace panel as this seems to still be a bottleneck point) Screenshot 2023-07-10 at 14 52 41 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../third_party_vis_lens_example/kibana.jsonc | 3 - .../public/visualization.tsx | 25 +- .../tsconfig.json | 1 - .../lens_configuration_flyout.test.tsx | 2 +- .../datasources/form_based/datapanel.test.tsx | 4 - .../datasources/form_based/form_based.tsx | 209 ++++----------- .../datasources/text_based/datapanel.test.tsx | 3 +- .../text_based/text_based_languages.tsx | 222 +++++++-------- .../config_panel/layer_panel.test.tsx | 36 ++- .../editor_frame/config_panel/layer_panel.tsx | 154 +++++------ .../config_panel/layer_settings.test.tsx | 4 +- .../config_panel/layer_settings.tsx | 7 +- .../editor_frame/data_panel_wrapper.test.tsx | 11 +- .../editor_frame/data_panel_wrapper.tsx | 16 +- .../editor_frame/editor_frame.test.tsx | 54 ++-- .../workspace_panel_wrapper.test.tsx | 8 +- .../workspace_panel_wrapper.tsx | 29 +- ...datasource_mock.ts => datasource_mock.tsx} | 11 +- .../plugins/lens/public/mocks/store_mocks.tsx | 5 +- ...ization_mock.ts => visualization_mock.tsx} | 4 +- .../lens/public/native_renderer/index.ts | 8 - .../native_renderer/native_renderer.test.tsx | 252 ------------------ .../native_renderer/native_renderer.tsx | 66 ----- x-pack/plugins/lens/public/types.ts | 90 +++---- .../datatable/visualization.tsx | 47 +--- .../visualizations/gauge/visualization.tsx | 26 +- .../visualizations/heatmap/visualization.tsx | 26 +- .../legacy_metric/visualization.tsx | 25 +- .../visualizations/metric/visualization.tsx | 36 +-- .../partition/visualization.tsx | 48 +--- .../tagcloud/tagcloud_visualization.tsx | 34 +-- .../visualizations/xy/visualization.tsx | 131 ++------- .../lens/choropleth_chart/visualization.tsx | 23 +- 33 files changed, 424 insertions(+), 1196 deletions(-) rename x-pack/plugins/lens/public/mocks/{datasource_mock.ts => datasource_mock.tsx} (91%) rename x-pack/plugins/lens/public/mocks/{visualization_mock.ts => visualization_mock.tsx} (96%) delete mode 100644 x-pack/plugins/lens/public/native_renderer/index.ts delete mode 100644 x-pack/plugins/lens/public/native_renderer/native_renderer.test.tsx delete mode 100644 x-pack/plugins/lens/public/native_renderer/native_renderer.tsx diff --git a/x-pack/examples/third_party_vis_lens_example/kibana.jsonc b/x-pack/examples/third_party_vis_lens_example/kibana.jsonc index 27d9ae28d42b9..90352c4e8fe2d 100644 --- a/x-pack/examples/third_party_vis_lens_example/kibana.jsonc +++ b/x-pack/examples/third_party_vis_lens_example/kibana.jsonc @@ -16,9 +16,6 @@ "developerExamples", "expressions", "fieldFormats" - ], - "requiredBundles": [ - "kibanaReact" ] } } diff --git a/x-pack/examples/third_party_vis_lens_example/public/visualization.tsx b/x-pack/examples/third_party_vis_lens_example/public/visualization.tsx index 83813a590f6c6..60b45bad9c423 100644 --- a/x-pack/examples/third_party_vis_lens_example/public/visualization.tsx +++ b/x-pack/examples/third_party_vis_lens_example/public/visualization.tsx @@ -7,10 +7,8 @@ import React from 'react'; import { EuiFormRow, EuiColorPicker } from '@elastic/eui'; -import { render } from 'react-dom'; import { Ast } from '@kbn/interpreter'; import { ThemeServiceStart } from '@kbn/core/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { Visualization, OperationMetadata } from '@kbn/lens-plugin/public'; import { layerTypes } from '@kbn/lens-plugin/public'; import type { RotatingNumberState } from '../common/types'; @@ -166,19 +164,16 @@ export const getRotatingNumberVisualization = ({ return { ...prevState, accessor: undefined }; }, - renderDimensionEditor(domElement, props) { - render( - - - { - props.setState({ ...props.state, color: newColor }); - }} - color={props.state.color} - /> - - , - domElement + DimensionEditorComponent(props) { + return ( + + { + props.setState({ ...props.state, color: newColor }); + }} + color={props.state.color} + /> + ); }, }); diff --git a/x-pack/examples/third_party_vis_lens_example/tsconfig.json b/x-pack/examples/third_party_vis_lens_example/tsconfig.json index ef98a7a9f4479..50b96685bd3d8 100644 --- a/x-pack/examples/third_party_vis_lens_example/tsconfig.json +++ b/x-pack/examples/third_party_vis_lens_example/tsconfig.json @@ -16,7 +16,6 @@ "kbn_references": [ "@kbn/core", "@kbn/expressions-plugin", - "@kbn/kibana-react-plugin", "@kbn/data-views-plugin", "@kbn/field-formats-plugin", "@kbn/lens-plugin", diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx index 3a14b26f5d9cc..f1a2ba0630993 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx @@ -196,6 +196,7 @@ describe('LensEditConfigurationFlyout', () => { const { instance } = await prepareAndMountComponent(props); expect(instance.find(VisualizationToolbar).prop('activeVisualization')).toMatchInlineSnapshot(` Object { + "DimensionEditorComponent": [MockFunction], "appendLayer": [MockFunction], "clearLayer": [MockFunction], "getConfiguration": [MockFunction] { @@ -414,7 +415,6 @@ describe('LensEditConfigurationFlyout', () => { "initialize": [MockFunction], "removeDimension": [MockFunction], "removeLayer": [MockFunction], - "renderDimensionEditor": [MockFunction], "setDimension": [MockFunction], "switchVisualizationType": [MockFunction], "toExpression": [MockFunction], diff --git a/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx index e583d2fa7d796..01a31f98000f9 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx @@ -7,7 +7,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { createMockedDragDropContext } from '../../mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks, @@ -408,9 +407,6 @@ describe('FormBased Data Panel', () => { dataViews, }), setState: jest.fn(), - dragDropContext: createMockedDragDropContext({ - dragging: { id: '1', humanData: { label: 'Label' } }, - }), dateRange: { fromDate: '2019-01-01', toDate: '2020-01-01' }, frame: getFrameAPIMock({ indexPatterns: indexPatterns as unknown as DataViewsState['indexPatterns'], diff --git a/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx index 533cdb179f64a..98954f601649d 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx @@ -6,8 +6,6 @@ */ import React from 'react'; -import { render } from 'react-dom'; -import { I18nProvider } from '@kbn/i18n-react'; import type { CoreStart, SavedObjectReference } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { TimeRange } from '@kbn/es-query'; @@ -16,7 +14,6 @@ import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import { flatten, isEqual } from 'lodash'; import type { DataViewsPublicPluginStart, DataView } from '@kbn/data-views-plugin/public'; import type { IndexPatternFieldEditorStart } from '@kbn/data-view-field-editor-plugin/public'; -import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { DataPublicPluginStart, UI_SETTINGS } from '@kbn/data-plugin/public'; import { VisualizeFieldContext } from '@kbn/ui-actions-plugin/public'; import { ChartsPluginSetup } from '@kbn/charts-plugin/public'; @@ -25,7 +22,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; import { EuiButton } from '@elastic/eui'; import type { SharePluginStart } from '@kbn/share-plugin/public'; -import { ChildDragDropProvider, type DraggingIdentifier } from '@kbn/dom-drag-drop'; +import { type DraggingIdentifier } from '@kbn/dom-drag-drop'; import { DimensionTrigger } from '@kbn/visualization-ui-components/public'; import memoizeOne from 'memoize-one'; import type { @@ -191,7 +188,7 @@ export function getFormBasedDatasource({ dataViewFieldEditor: IndexPatternFieldEditorStart; uiActions: UiActionsStart; }) { - const { uiSettings, settings } = core; + const { uiSettings } = core; const DATASOURCE_ID = 'formBased'; const ALIAS_IDS = ['indexpattern']; @@ -452,68 +449,27 @@ export function getFormBasedDatasource({ searchSessionId ), - renderLayerSettings(domElement, props) { - render( - - - - - - - , - domElement - ); + LayerSettingsComponent(props) { + return ; }, - - renderDataPanel(domElement: Element, props: DatasourceDataPanelProps) { - const { onChangeIndexPattern, dragDropContext, ...otherProps } = props; + DataPanelComponent(props: DatasourceDataPanelProps) { + const { onChangeIndexPattern, ...otherProps } = props; const layerFields = formBasedDatasource?.getSelectedFields?.(props.state); - - render( - - - - - - - - - , - domElement + return ( + ); }, - uniqueLabels(state: FormBasedPrivateState, indexPatternsMap: IndexPatternMap) { const layers = state.layers; const columnLabelMap = {} as Record; @@ -540,115 +496,48 @@ export function getFormBasedDatasource({ return columnLabelMap; }, - renderDimensionTrigger: ( - domElement: Element, - props: DatasourceDimensionTriggerProps - ) => { + DimensionTriggerComponent: (props: DatasourceDimensionTriggerProps) => { const columnLabelMap = formBasedDatasource.uniqueLabels(props.state, props.indexPatterns); const uniqueLabel = columnLabelMap[props.columnId]; const formattedLabel = wrapOnDot(uniqueLabel); - render( - - - - - - - , - domElement - ); + return ; }, - renderDimensionEditor: ( - domElement: Element, - props: DatasourceDimensionEditorProps - ) => { + DimensionEditorComponent: (props: DatasourceDimensionEditorProps) => { const columnLabelMap = formBasedDatasource.uniqueLabels(props.state, props.indexPatterns); - render( - - - - - - - , - domElement + return ( + ); }, - renderLayerPanel: ( - domElement: Element, - props: DatasourceLayerPanelProps - ) => { + LayerPanelComponent: (props: DatasourceLayerPanelProps) => { const { onChangeIndexPattern, ...otherProps } = props; - render( - - - - { - triggerActionOnIndexPatternChange({ - indexPatternId, - state: props.state, - layerId: props.layerId, - uiActions, - }); - onChangeIndexPattern(indexPatternId, DATASOURCE_ID, props.layerId); - }} - {...otherProps} - /> - - - , - domElement + return ( + { + triggerActionOnIndexPatternChange({ + indexPatternId, + state: props.state, + layerId: props.layerId, + uiActions, + }); + onChangeIndexPattern(indexPatternId, DATASOURCE_ID, props.layerId); + }} + {...otherProps} + /> ); }, diff --git a/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx index 210678fa909f3..001e2d5b99af8 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx @@ -28,7 +28,7 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { createIndexPatternServiceMock } from '../../mocks/data_views_service_mock'; -import { createMockFramePublicAPI, createMockedDragDropContext } from '../../mocks'; +import { createMockFramePublicAPI } from '../../mocks'; import { DataViewsState } from '../../state_management'; const fieldsFromQuery = [ @@ -184,7 +184,6 @@ describe('TextBased Query Languages Data Panel', () => { ]) ), }, - dragDropContext: createMockedDragDropContext(), core, dateRange: { fromDate: 'now-7d', diff --git a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx index f93efd9835ee2..831bb1501c8fc 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx @@ -6,15 +6,12 @@ */ import React from 'react'; -import { render } from 'react-dom'; -import { I18nProvider } from '@kbn/i18n-react'; import { CoreStart } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import type { AggregateQuery } from '@kbn/es-query'; import type { SavedObjectReference } from '@kbn/core/public'; import { EuiFormRow } from '@elastic/eui'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import type { ExpressionsStart, DatatableColumnType } from '@kbn/expressions-plugin/public'; import type { DataViewsPublicPluginStart, DataView } from '@kbn/data-views-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; @@ -22,7 +19,6 @@ import { euiThemeVars } from '@kbn/ui-theme'; import { DimensionTrigger } from '@kbn/visualization-ui-components/public'; import memoizeOne from 'memoize-one'; import { isEqual } from 'lodash'; -import { ChildDragDropProvider } from '@kbn/dom-drag-drop'; import { DatasourceDimensionEditorProps, DatasourceDataPanelProps, @@ -364,31 +360,20 @@ export function getTextBasedDatasource({ ); }, - renderDataPanel(domElement: Element, props: DatasourceDataPanelProps) { + DataPanelComponent(props: DatasourceDataPanelProps) { const layerFields = TextBasedDatasource?.getSelectedFields?.(props.state); - const { dragDropContext, ...otherProps } = props; - render( - - - - - - - , - domElement + return ( + ); }, - renderDimensionTrigger: ( - domElement: Element, - props: DatasourceDimensionTriggerProps - ) => { + DimensionTriggerComponent: (props: DatasourceDimensionTriggerProps) => { const columnLabelMap = TextBasedDatasource.uniqueLabels(props.state, props.indexPatterns); const layer = props.state.layers[props.layerId]; const selectedField = layer?.allColumns?.find((column) => column.columnId === props.columnId); @@ -397,23 +382,18 @@ export function getTextBasedDatasource({ customLabel = selectedField?.fieldName; } - render( - - - {' '} - - , - domElement + return ( + ); }, @@ -421,10 +401,7 @@ export function getTextBasedDatasource({ return []; }, - renderDimensionEditor: ( - domElement: Element, - props: DatasourceDimensionEditorProps - ) => { + DimensionEditorComponent: (props: DatasourceDimensionEditorProps) => { const fields = props.state.fieldList; const selectedField = props.state.layers[props.layerId]?.allColumns?.find( (column) => column.columnId === props.columnId @@ -442,94 +419,81 @@ export function getTextBasedDatasource({ : true, }; }); - render( - - - - { - const meta = fields.find((f) => f.name === choice.field)?.meta; - const newColumn = { - columnId: props.columnId, - fieldName: choice.field, - meta, - }; - return props.setState( - !selectedField - ? { - ...props.state, - layers: { - ...props.state.layers, - [props.layerId]: { - ...props.state.layers[props.layerId], - columns: [...props.state.layers[props.layerId].columns, newColumn], - allColumns: [ - ...props.state.layers[props.layerId].allColumns, - newColumn, - ], - }, + return ( + <> + + { + const meta = fields.find((f) => f.name === choice.field)?.meta; + const newColumn = { + columnId: props.columnId, + fieldName: choice.field, + meta, + }; + return props.setState( + !selectedField + ? { + ...props.state, + layers: { + ...props.state.layers, + [props.layerId]: { + ...props.state.layers[props.layerId], + columns: [...props.state.layers[props.layerId].columns, newColumn], + allColumns: [ + ...props.state.layers[props.layerId].allColumns, + newColumn, + ], }, - } - : { - ...props.state, - layers: { - ...props.state.layers, - [props.layerId]: { - ...props.state.layers[props.layerId], - columns: props.state.layers[props.layerId].columns.map((col) => - col.columnId !== props.columnId - ? col - : { ...col, fieldName: choice.field, meta } - ), - allColumns: props.state.layers[props.layerId].allColumns.map((col) => - col.columnId !== props.columnId - ? col - : { ...col, fieldName: choice.field, meta } - ), - }, + }, + } + : { + ...props.state, + layers: { + ...props.state.layers, + [props.layerId]: { + ...props.state.layers[props.layerId], + columns: props.state.layers[props.layerId].columns.map((col) => + col.columnId !== props.columnId + ? col + : { ...col, fieldName: choice.field, meta } + ), + allColumns: props.state.layers[props.layerId].allColumns.map((col) => + col.columnId !== props.columnId + ? col + : { ...col, fieldName: choice.field, meta } + ), }, - } - ); - }} - /> - - {props.dataSectionExtra && ( -
- {props.dataSectionExtra} -
- )} -
-
, - domElement + }, + } + ); + }} + /> + + {props.dataSectionExtra && ( +
+ {props.dataSectionExtra} +
+ )} + ); }, - renderLayerPanel: ( - domElement: Element, - props: DatasourceLayerPanelProps - ) => { - render( - - - - - , - domElement - ); + LayerPanelComponent: (props: DatasourceLayerPanelProps) => { + return ; }, uniqueLabels(state: TextBasedPrivateState) { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx index 9db931efeda26..bb258c4bd690f 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx @@ -390,7 +390,7 @@ describe('LayerPanel', () => { }, ], }); - mockVisualization.renderDimensionEditor = jest.fn(); + mockVisualization.DimensionEditorComponent = jest.fn().mockImplementation(() =>
); const { instance } = await mountWithProvider(); act(() => { @@ -434,14 +434,13 @@ describe('LayerPanel', () => { }); instance.update(); - expect(mockDatasource.renderDimensionEditor).toHaveBeenCalledWith( - expect.any(Element), + expect(mockDatasource.DimensionEditorComponent).toHaveBeenCalledWith( expect.objectContaining({ columnId: 'newid' }) ); const stateFn = - mockDatasource.renderDimensionEditor.mock.calls[ - mockDatasource.renderDimensionEditor.mock.calls.length - 1 - ][1].setState; + mockDatasource.DimensionEditorComponent.mock.calls[ + mockDatasource.DimensionEditorComponent.mock.calls.length - 1 + ][0].setState; act(() => { stateFn( @@ -512,14 +511,13 @@ describe('LayerPanel', () => { }); instance.update(); - expect(mockDatasource.renderDimensionEditor).toHaveBeenCalledWith( - expect.any(Element), + expect(mockDatasource.DimensionEditorComponent).toHaveBeenCalledWith( expect.objectContaining({ columnId: 'y' }) ); const stateFn = - mockDatasource.renderDimensionEditor.mock.calls[ - mockDatasource.renderDimensionEditor.mock.calls.length - 1 - ][1].setState; + mockDatasource.DimensionEditorComponent.mock.calls[ + mockDatasource.DimensionEditorComponent.mock.calls.length - 1 + ][0].setState; act(() => { stateFn( @@ -586,9 +584,9 @@ describe('LayerPanel', () => { expect(instance.find('EuiFlyoutHeader').exists()).toBe(true); const lastArgs = - mockDatasource.renderDimensionEditor.mock.calls[ - mockDatasource.renderDimensionEditor.mock.calls.length - 1 - ][1]; + mockDatasource.DimensionEditorComponent.mock.calls[ + mockDatasource.DimensionEditorComponent.mock.calls.length - 1 + ][0]; // Simulate what is called by the dimension editor act(() => { @@ -597,7 +595,7 @@ describe('LayerPanel', () => { }); }); - expect(mockVisualization.renderDimensionEditor).toHaveBeenCalled(); + expect(mockVisualization.DimensionEditorComponent).toHaveBeenCalled(); }); it('should close the DimensionContainer when the active visualization changes', async () => { @@ -1331,7 +1329,7 @@ describe('LayerPanel', () => { ], }); await mountWithProvider(); - expect(mockDatasource.renderDimensionTrigger).toHaveBeenCalled(); + expect(mockDatasource.DimensionTriggerComponent).toHaveBeenCalled(); }); it('should render visualization dimension trigger if there is no layer datasource', async () => { @@ -1354,14 +1352,14 @@ describe('LayerPanel', () => { framePublicAPI: { ...props.framePublicAPI, datasourceLayers: {} }, }; - mockVisualization.renderDimensionTrigger = jest.fn(); + mockVisualization.DimensionTriggerComponent = jest.fn().mockImplementation(() =>
); mockVisualization.getUniqueLabels = jest.fn(() => ({ x: 'A', })); await mountWithProvider(); - expect(mockDatasource.renderDimensionTrigger).not.toHaveBeenCalled(); - expect(mockVisualization.renderDimensionTrigger).toHaveBeenCalled(); + expect(mockDatasource.DimensionTriggerComponent).not.toHaveBeenCalled(); + expect(mockVisualization.DimensionTriggerComponent).toHaveBeenCalled(); }); // TODO - test user message display diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index 83f06e84659e1..f957886ce033a 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -24,7 +24,6 @@ import { DragDropIdentifier, ReorderProvider, DropType } from '@kbn/dom-drag-dro import { DimensionButton, DimensionTrigger } from '@kbn/visualization-ui-components/public'; import { LayerActions } from './layer_actions'; import { IndexPatternServiceAPI } from '../../../data_views_service/service'; -import { NativeRenderer } from '../../../native_renderer'; import { StateSetter, Visualization, @@ -374,8 +373,8 @@ export function LayerPanel( isTextBasedLanguage, hasLayerSettings: Boolean( (Object.values(visualizationLayerSettings).some(Boolean) && - activeVisualization.renderLayerSettings) || - layerDatasource?.renderLayerSettings + activeVisualization.LayerSettingsComponent) || + layerDatasource?.LayerSettingsComponent ), openLayerSettings: () => setPanelSettingsOpen(true), onCloneLayer, @@ -398,7 +397,7 @@ export function LayerPanel( isOnlyLayer, isTextBasedLanguage, visualizationLayerSettings, - layerDatasource?.renderLayerSettings, + layerDatasource?.LayerSettingsComponent, onCloneLayer, onRemoveLayer, ] @@ -438,11 +437,12 @@ export function LayerPanel( )} {props.indexPatternService && - (layerDatasource || activeVisualization.renderLayerPanel) && } + (layerDatasource || activeVisualization.LayerPanelComponent) && ( + + )} {layerDatasource && props.indexPatternService && ( - )} - {activeVisualization.renderLayerPanel && ( - {layerDatasource ? ( - + {layerDatasource.DimensionTriggerComponent({ ...layerDatasourceConfigProps, columnId: accessorConfig.columnId, groupId: group.groupId, filterOperations: group.filterOperations, indexPatterns: dataViews.indexPatterns, - }} - /> + })} + ) : ( <> - {activeVisualization?.renderDimensionTrigger?.({ + {activeVisualization?.DimensionTriggerComponent?.({ columnId, label: columnLabelMap?.[columnId] ?? '', hideTooltip, @@ -705,7 +703,7 @@ export function LayerPanel( })} - {(layerDatasource?.renderLayerSettings || activeVisualization?.renderLayerSettings) && ( + {(layerDatasource?.LayerSettingsComponent || activeVisualization?.LayerSettingsComponent) && ( (settingsPanelRef.current = el)} isOpen={isPanelSettingsOpen} @@ -721,7 +719,7 @@ export function LayerPanel( >
- {layerDatasource?.renderLayerSettings || visualizationLayerSettings.data ? ( + {layerDatasource?.LayerSettingsComponent || visualizationLayerSettings.data ? ( ) : null} - {layerDatasource?.renderLayerSettings && ( + {layerDatasource?.LayerSettingsComponent && ( <> - + )} - {layerDatasource?.renderLayerSettings && visualizationLayerSettings.data ? ( + {layerDatasource?.LayerSettingsComponent && visualizationLayerSettings.data ? ( ) : null} - {activeVisualization?.renderLayerSettings && visualizationLayerSettings.data ? ( - ) : null} - {activeVisualization?.renderLayerSettings && ( - - {activeGroup && activeId && layerDatasource && ( - - ), - }} - /> - )} + {activeGroup && + activeId && + layerDatasource && + layerDatasource.DimensionEditorComponent({ + ...layerDatasourceConfigProps, + core: props.core, + columnId: activeId, + groupId: activeGroup.groupId, + hideGrouping: activeGroup.hideGrouping, + filterOperations: activeGroup.filterOperations, + isMetricDimension: activeGroup?.isMetricDimension, + dimensionGroups, + toggleFullscreen, + isFullscreen, + setState: updateDataLayerState, + supportStaticValue: Boolean(activeGroup.supportStaticValue), + paramEditorCustomProps: activeGroup.paramEditorCustomProps, + enableFormatSelector: activeGroup.enableFormatSelector !== false, + layerType: activeVisualization.getLayerType(layerId, visualizationState), + indexPatterns: dataViews.indexPatterns, + activeData: layerVisualizationConfigProps.activeData, + dataSectionExtra: !isFullscreen && + !activeDimension.isNew && + activeVisualization.DimensionEditorDataExtraComponent && ( + + ), + })} {activeGroup && activeId && !isFullscreen && !activeDimension.isNew && - activeVisualization.renderDimensionEditor && + activeVisualization.DimensionEditorComponent && activeGroup?.enableDimensionEditor && ( <>
-
- {activeVisualization.renderDimensionEditorAdditionalSection && ( - { }); it('should call the custom renderer if available', async () => { - mockVisualization.renderLayerHeader = jest.fn(); + mockVisualization.LayerHeaderComponent = jest.fn().mockImplementation(() =>
); await mountWithProvider(); - expect(mockVisualization.renderLayerHeader).toHaveBeenCalled(); + expect(mockVisualization.LayerHeaderComponent).toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_settings.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_settings.tsx index fc88ff2af8bbe..f04b2a93835df 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_settings.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_settings.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import { NativeRenderer } from '../../../native_renderer'; import { Visualization, VisualizationLayerWidgetProps } from '../../../types'; import { StaticHeader } from '../../../shared_components'; @@ -17,7 +16,7 @@ export function LayerSettings({ activeVisualization: Visualization; layerConfigProps: VisualizationLayerWidgetProps; }) { - if (!activeVisualization.renderLayerHeader) { + if (!activeVisualization.LayerHeaderComponent) { const description = activeVisualization.getDescription(layerConfigProps.state); if (!description) { return null; @@ -25,7 +24,5 @@ export function LayerSettings({ return ; } - return ( - - ); + return ; } diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.test.tsx index b2ac0786e3302..028c6551d85c9 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.test.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import { DragDropIdentifier } from '@kbn/dom-drag-drop'; import { DataPanelWrapper } from './data_panel_wrapper'; import { Datasource, DatasourceDataPanelProps, VisualizationMap } from '../../types'; import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; @@ -22,11 +21,11 @@ describe('Data Panel Wrapper', () => { let datasourceDataPanelProps: DatasourceDataPanelProps; let lensStore: Awaited>['lensStore']; beforeEach(async () => { - const renderDataPanel = jest.fn(); + const DataPanelComponent = jest.fn().mockImplementation(() =>
); const datasourceMap = { activeDatasource: { - renderDataPanel, + DataPanelComponent, getUsedDataViews: jest.fn(), getLayers: jest.fn(() => []), } as unknown as Datasource, @@ -38,8 +37,8 @@ describe('Data Panel Wrapper', () => { visualizationMap={{} as VisualizationMap} showNoDataPopover={() => {}} core={{} as DatasourceDataPanelProps['core']} - dropOntoWorkspace={(field: DragDropIdentifier) => {}} - hasSuggestionForField={(field: DragDropIdentifier) => true} + dropOntoWorkspace={() => {}} + hasSuggestionForField={() => true} plugins={{ uiActions: {} as UiActionsStart, dataViews: {} as DataViewsPublicPluginStart, @@ -66,7 +65,7 @@ describe('Data Panel Wrapper', () => { lensStore = mountResult.lensStore; - datasourceDataPanelProps = renderDataPanel.mock.calls[0][1] as DatasourceDataPanelProps; + datasourceDataPanelProps = DataPanelComponent.mock.calls[0][0] as DatasourceDataPanelProps; }); describe('setState', () => { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx index a933f6865f08e..394c301d8baf6 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx @@ -12,11 +12,10 @@ import { Storage } from '@kbn/kibana-utils-plugin/public'; import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { EventAnnotationServiceType } from '@kbn/event-annotation-plugin/public'; -import { useDragDropContext, DragDropIdentifier } from '@kbn/dom-drag-drop'; +import { DragDropIdentifier } from '@kbn/dom-drag-drop'; import memoizeOne from 'memoize-one'; import { isEqual } from 'lodash'; import { Easteregg } from './easteregg'; -import { NativeRenderer } from '../../native_renderer'; import { StateSetter, DatasourceDataPanelProps, @@ -162,7 +161,6 @@ export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => { const datasourceProps: DatasourceDataPanelProps = { ...externalContext, - dragDropContext: useDragDropContext(), state: activeDatasourceId ? datasourceStates[activeDatasourceId].state : null, setState: setDatasourceState, core: props.core, @@ -187,16 +185,16 @@ export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => { []), ]), }; + const DataPanelComponent = + activeDatasourceId && !datasourceIsLoading + ? props.datasourceMap[activeDatasourceId].DataPanelComponent + : null; return ( <> - {activeDatasourceId && !datasourceIsLoading && ( - + {DataPanelComponent && ( +
{DataPanelComponent(datasourceProps)}
)} ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx index 8571b2ca347b0..988bb0bb65592 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { useEffect } from 'react'; import { ReactWrapper } from 'enzyme'; // Tests are executed in a jsdom environment who does not have sizing methods, @@ -41,7 +41,7 @@ import { } from '../../mocks'; import { inspectorPluginMock } from '@kbn/inspector-plugin/public/mocks'; import { ReactExpressionRendererType } from '@kbn/expressions-plugin/public'; -import { DragDrop } from '@kbn/dom-drag-drop'; +import { DragDrop, useDragDropContext } from '@kbn/dom-drag-drop'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { expressionsPluginMock } from '@kbn/expressions-plugin/public/mocks'; @@ -177,7 +177,7 @@ describe('editor_frame', () => { }, }, }); - expect(mockDatasource.renderDataPanel).not.toHaveBeenCalled(); + expect(mockDatasource.DataPanelComponent).not.toHaveBeenCalled(); lensStore.dispatch( setState({ datasourceStates: { @@ -190,7 +190,7 @@ describe('editor_frame', () => { }, }) ); - expect(mockDatasource.renderDataPanel).toHaveBeenCalled(); + expect(mockDatasource.DataPanelComponent).toHaveBeenCalled(); }); it('should initialize visualization state and render config panel', async () => { @@ -304,7 +304,7 @@ describe('editor_frame', () => { }, }); const updatedState = {}; - const setDatasourceState = (mockDatasource.renderDataPanel as jest.Mock).mock.calls[0][1] + const setDatasourceState = (mockDatasource.DataPanelComponent as jest.Mock).mock.calls[0][0] .setState; act(() => { setDatasourceState(updatedState); @@ -334,10 +334,10 @@ describe('editor_frame', () => { }; await mountWithProvider(); - const setDatasourceState = (mockDatasource.renderDataPanel as jest.Mock).mock.calls[0][1] + const setDatasourceState = (mockDatasource.DataPanelComponent as jest.Mock).mock.calls[0][0] .setState; - mockDatasource.renderDataPanel.mockClear(); + mockDatasource.DataPanelComponent.mockClear(); const updatedState = { title: 'shazm', @@ -346,9 +346,8 @@ describe('editor_frame', () => { setDatasourceState(updatedState); }); - expect(mockDatasource.renderDataPanel).toHaveBeenCalledTimes(1); - expect(mockDatasource.renderDataPanel).toHaveBeenLastCalledWith( - expect.any(Element), + expect(mockDatasource.DataPanelComponent).toHaveBeenCalledTimes(1); + expect(mockDatasource.DataPanelComponent).toHaveBeenLastCalledWith( expect.objectContaining({ state: updatedState, }) @@ -385,7 +384,7 @@ describe('editor_frame', () => { }; mockDatasource.getPublicAPI.mockReturnValue(updatedPublicAPI); - const setDatasourceState = (mockDatasource.renderDataPanel as jest.Mock).mock.calls[0][1] + const setDatasourceState = (mockDatasource.DataPanelComponent as jest.Mock).mock.calls[0][0] .setState; act(() => { setDatasourceState({}); @@ -722,8 +721,7 @@ describe('editor_frame', () => { state: suggestionVisState, }) ); - expect(mockDatasource.renderDataPanel).toHaveBeenLastCalledWith( - expect.any(Element), + expect(mockDatasource.DataPanelComponent).toHaveBeenLastCalledWith( expect.objectContaining({ state: newDatasourceState, }) @@ -820,19 +818,7 @@ describe('editor_frame', () => { getDatasourceSuggestionsForField: () => [generateSuggestion()], getDatasourceSuggestionsFromCurrentState: () => [generateSuggestion()], getDatasourceSuggestionsForVisualizeField: () => [generateSuggestion()], - renderDataPanel: (_element, { dragDropContext: [{ dragging }, dndDispatch] }) => { - if (!dragging || dragging.id !== 'draggedField') { - dndDispatch({ - type: 'startDragging', - payload: { - dragging: { - id: 'draggedField', - humanData: { label: 'draggedField' }, - }, - }, - }); - } - }, + DataPanelComponent: jest.fn().mockImplementation(() =>
), }, }, @@ -863,7 +849,7 @@ describe('editor_frame', () => { id: '1', humanData: { label: 'draggedField' }, }, - 'field_replace' + 'field_add' ); }); @@ -927,8 +913,9 @@ describe('editor_frame', () => { getDatasourceSuggestionsForField: () => [generateSuggestion()], getDatasourceSuggestionsFromCurrentState: () => [generateSuggestion()], getDatasourceSuggestionsForVisualizeField: () => [generateSuggestion()], - renderDataPanel: (_element, { dragDropContext: [{ dragging }, dndDispatch] }) => { - if (!dragging || dragging.id !== 'draggedField') { + DataPanelComponent: jest.fn().mockImplementation(() => { + const [, dndDispatch] = useDragDropContext(); + useEffect(() => { dndDispatch({ type: 'startDragging', payload: { @@ -938,15 +925,16 @@ describe('editor_frame', () => { }, }, }); - } - }, + }, [dndDispatch]); + return
; + }), }, }, - ExpressionRenderer: expressionRendererMock, } as EditorFrameProps; instance = (await mountWithProvider()).instance; + instance.update(); act(() => { @@ -959,7 +947,7 @@ describe('editor_frame', () => { label: 'label', }, }, - 'field_replace' + 'field_add' ); }); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.test.tsx index 700fe7f96bf84..9811b59b7b30c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.test.tsx @@ -51,7 +51,7 @@ describe('workspace_panel_wrapper', () => { }); it('should call the toolbar renderer if provided', async () => { - const renderToolbarMock = jest.fn(); + const ToolbarComponentMock = jest.fn(() => null); const visState = { internalState: 123 }; await mountWithProvider( { visualizationState={visState} children={} visualizationId="myVis" - visualizationMap={{ myVis: { ...mockVisualization, renderToolbar: renderToolbarMock } }} + visualizationMap={{ + myVis: { ...mockVisualization, ToolbarComponent: ToolbarComponentMock }, + }} datasourceMap={{}} datasourceStates={{}} isFullscreen={false} @@ -74,7 +76,7 @@ describe('workspace_panel_wrapper', () => { } ); - expect(renderToolbarMock).toHaveBeenCalledWith(expect.any(Element), { + expect(ToolbarComponentMock).toHaveBeenCalledWith({ state: visState, frame: mockFrameAPI, setState: expect.anything(), diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx index 064b268209aea..9469a903131bd 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx @@ -19,7 +19,6 @@ import { Visualization, } from '../../../types'; import { DONT_CLOSE_DIMENSION_CONTAINER_ON_CLICK_CLASS } from '../../../utils'; -import { NativeRenderer } from '../../../native_renderer'; import { ChartSwitch } from './chart_switch'; import { MessageList } from './message_list'; import { @@ -59,37 +58,37 @@ export function VisualizationToolbar(props: { const { activeDatasourceId, visualization, datasourceStates } = useLensSelector( (state) => state.lens ); + const { activeVisualization, onUpdateStateCb } = props; const setVisualizationState = useCallback( (newState: unknown) => { - if (!props.activeVisualization) { + if (!activeVisualization) { return; } dispatchLens( updateVisualizationState({ - visualizationId: props.activeVisualization.id, + visualizationId: activeVisualization.id, newState, }) ); - if (activeDatasourceId && props.onUpdateStateCb) { + if (activeDatasourceId && onUpdateStateCb) { const dsState = datasourceStates[activeDatasourceId].state; - props.onUpdateStateCb?.(dsState, newState); + onUpdateStateCb?.(dsState, newState); } }, - [activeDatasourceId, datasourceStates, dispatchLens, props] + [activeDatasourceId, datasourceStates, dispatchLens, activeVisualization, onUpdateStateCb] ); + const ToolbarComponent = props.activeVisualization?.ToolbarComponent; + return ( <> - {props.activeVisualization && props.activeVisualization.renderToolbar && ( + {ToolbarComponent && ( - + {ToolbarComponent({ + frame: props.framePublicAPI, + state: visualization.state, + setState: setVisualizationState, + })} )} diff --git a/x-pack/plugins/lens/public/mocks/datasource_mock.ts b/x-pack/plugins/lens/public/mocks/datasource_mock.tsx similarity index 91% rename from x-pack/plugins/lens/public/mocks/datasource_mock.ts rename to x-pack/plugins/lens/public/mocks/datasource_mock.tsx index 9417837a14b84..e4f9f5c88fdc1 100644 --- a/x-pack/plugins/lens/public/mocks/datasource_mock.ts +++ b/x-pack/plugins/lens/public/mocks/datasource_mock.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import React from 'react'; import { DatasourcePublicAPI, Datasource } from '../types'; export type DatasourceMock = jest.Mocked & { @@ -44,8 +44,6 @@ export function createMockDatasource( getRenderEventCounters: jest.fn((_state) => []), getPublicAPI: jest.fn().mockReturnValue(publicAPIMock), initialize: jest.fn((_state?) => {}), - renderDataPanel: jest.fn(), - renderLayerPanel: jest.fn(), toExpression: jest.fn((_frame, _state, _indexPatterns, dateRange, nowInstant) => null), insertLayer: jest.fn((_state, _newLayerId) => ({})), removeLayer: jest.fn((state, layerId) => ({ newState: state, removedLayerIds: [layerId] })), @@ -53,8 +51,6 @@ export function createMockDatasource( removeColumn: jest.fn((props) => {}), getLayers: jest.fn((_state) => []), uniqueLabels: jest.fn((_state, dataViews) => ({})), - renderDimensionTrigger: jest.fn(), - renderDimensionEditor: jest.fn(), getDropProps: jest.fn(), onDrop: jest.fn(), createEmptyLayer: jest.fn(), @@ -71,6 +67,11 @@ export function createMockDatasource( getUsedDataViews: jest.fn(), onRefreshIndexPattern: jest.fn(), getDatasourceInfo: jest.fn(), + + DataPanelComponent: jest.fn().mockImplementation(() =>
), + LayerPanelComponent: jest.fn().mockImplementation(() =>
), + DimensionTriggerComponent: jest.fn().mockImplementation(() =>
), + DimensionEditorComponent: jest.fn().mockImplementation(() =>
), }; } diff --git a/x-pack/plugins/lens/public/mocks/store_mocks.tsx b/x-pack/plugins/lens/public/mocks/store_mocks.tsx index d4ba2d042b1ca..d6866438719f8 100644 --- a/x-pack/plugins/lens/public/mocks/store_mocks.tsx +++ b/x-pack/plugins/lens/public/mocks/store_mocks.tsx @@ -100,6 +100,7 @@ export const mountWithProvider = async ( wrappingComponent?: React.FC<{ children: React.ReactNode; }>; + wrappingComponentProps?: Record; attachTo?: HTMLElement; } ) => { @@ -120,6 +121,7 @@ export const getMountWithProviderParams = ( wrappingComponent?: React.FC<{ children: React.ReactNode; }>; + wrappingComponentProps?: Record; attachTo?: HTMLElement; } ) => { @@ -133,12 +135,13 @@ export const getMountWithProviderParams = ( attachTo?: HTMLElement | undefined; } = {}; if (options) { - const { wrappingComponent: _wrappingComponent, ...rest } = options; + const { wrappingComponent: _wrappingComponent, wrappingComponentProps, ...rest } = options; restOptions = rest; if (_wrappingComponent) { wrappingComponent = ({ children }) => { return _wrappingComponent({ + ...wrappingComponentProps, children: {children}, }); }; diff --git a/x-pack/plugins/lens/public/mocks/visualization_mock.ts b/x-pack/plugins/lens/public/mocks/visualization_mock.tsx similarity index 96% rename from x-pack/plugins/lens/public/mocks/visualization_mock.ts rename to x-pack/plugins/lens/public/mocks/visualization_mock.tsx index 8c519c59b0072..80f20e8c3af4e 100644 --- a/x-pack/plugins/lens/public/mocks/visualization_mock.ts +++ b/x-pack/plugins/lens/public/mocks/visualization_mock.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import React from 'react'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; import { Visualization, VisualizationMap } from '../types'; @@ -49,7 +49,7 @@ export function createMockVisualization(id = 'testVis'): jest.Mocked
), }; } diff --git a/x-pack/plugins/lens/public/native_renderer/index.ts b/x-pack/plugins/lens/public/native_renderer/index.ts deleted file mode 100644 index 61a92b7101d02..0000000000000 --- a/x-pack/plugins/lens/public/native_renderer/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './native_renderer'; diff --git a/x-pack/plugins/lens/public/native_renderer/native_renderer.test.tsx b/x-pack/plugins/lens/public/native_renderer/native_renderer.test.tsx deleted file mode 100644 index 8796f619277ff..0000000000000 --- a/x-pack/plugins/lens/public/native_renderer/native_renderer.test.tsx +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useEffect } from 'react'; -import { render } from 'react-dom'; -import { NativeRenderer } from './native_renderer'; -import { act } from 'react-dom/test-utils'; - -function renderAndTriggerHooks(element: JSX.Element, mountpoint: Element) { - // act takes care of triggering state hooks - act(() => { - render(element, mountpoint); - }); -} - -describe('native_renderer', () => { - let mountpoint: Element; - - beforeEach(() => { - mountpoint = document.createElement('div'); - }); - - afterEach(() => { - mountpoint.remove(); - }); - - it('should render element in container', () => { - const renderSpy = jest.fn(); - const testProps = { a: 'abc' }; - - renderAndTriggerHooks( - , - mountpoint - ); - const containerElement = mountpoint.firstElementChild; - expect(renderSpy).toHaveBeenCalledWith(containerElement, testProps); - }); - - it('should render again if props change', () => { - const renderSpy = jest.fn(); - const testProps = { a: 'abc' }; - - renderAndTriggerHooks( - , - mountpoint - ); - renderAndTriggerHooks( - , - mountpoint - ); - renderAndTriggerHooks( - , - mountpoint - ); - expect(renderSpy).toHaveBeenCalledTimes(3); - const containerElement = mountpoint.firstElementChild; - expect(renderSpy).lastCalledWith(containerElement, { a: 'def' }); - }); - - it('should render again if props is just a string', () => { - const renderSpy = jest.fn(); - const testProps = 'abc'; - - renderAndTriggerHooks( - , - mountpoint - ); - renderAndTriggerHooks(, mountpoint); - renderAndTriggerHooks(, mountpoint); - expect(renderSpy).toHaveBeenCalledTimes(3); - const containerElement = mountpoint.firstElementChild; - expect(renderSpy).lastCalledWith(containerElement, 'def'); - }); - - it('should render again if props are extended', () => { - const renderSpy = jest.fn(); - const testProps = { a: 'abc' }; - - renderAndTriggerHooks( - , - mountpoint - ); - renderAndTriggerHooks( - , - mountpoint - ); - expect(renderSpy).toHaveBeenCalledTimes(2); - const containerElement = mountpoint.firstElementChild; - expect(renderSpy).lastCalledWith(containerElement, { a: 'abc', b: 'def' }); - }); - - it('should render again if props are limited', () => { - const renderSpy = jest.fn(); - const testProps = { a: 'abc', b: 'def' }; - - renderAndTriggerHooks( - , - mountpoint - ); - renderAndTriggerHooks( - , - mountpoint - ); - expect(renderSpy).toHaveBeenCalledTimes(2); - const containerElement = mountpoint.firstElementChild; - expect(renderSpy).lastCalledWith(containerElement, { a: 'abc' }); - }); - - it('should render a div as container', () => { - const renderSpy = jest.fn(); - const testProps = { a: 'abc' }; - - renderAndTriggerHooks( - , - mountpoint - ); - const containerElement: Element = mountpoint.firstElementChild!; - expect(containerElement.nodeName).toBe('DIV'); - }); - - it('should pass regular html attributes to the wrapping element', () => { - const renderSpy = jest.fn(); - const testProps = { a: 'abc' }; - - renderAndTriggerHooks( - , - mountpoint - ); - const containerElement: HTMLElement = mountpoint.firstElementChild! as HTMLElement; - expect(containerElement.className).toBe('testClass'); - expect(containerElement.dataset.testSubj).toBe('container'); - }); - - it('should render a specified element as container', () => { - const renderSpy = jest.fn(); - const testProps = { a: 'abc' }; - - renderAndTriggerHooks( - , - mountpoint - ); - const containerElement: Element = mountpoint.firstElementChild!; - expect(containerElement.nodeName).toBe('SPAN'); - }); - - it('should properly unmount a react element that is mounted inside the renderer', () => { - let isUnmounted = false; - - function TestComponent() { - useEffect(() => { - return () => { - isUnmounted = true; - }; - }, []); - return <>Hello; - } - - renderAndTriggerHooks( - { - // This render function mimics the most common usage inside Lens - render(, element); - }} - nativeProps={{}} - />, - mountpoint - ); - - // Replaces the component at the mountpoint with nothing - renderAndTriggerHooks(<>Empty, mountpoint); - - expect(isUnmounted).toBe(true); - }); - - it('should call the unmount function provided for non-react elements', () => { - const unmountCallback = jest.fn(); - - renderAndTriggerHooks( - { - return unmountCallback; - }} - nativeProps={{}} - />, - mountpoint - ); - - // Replaces the component at the mountpoint with nothing - renderAndTriggerHooks(<>Empty, mountpoint); - - expect(unmountCallback).toHaveBeenCalled(); - }); - - it('should handle when the mount function is asynchronous without a cleanup fn', () => { - let isUnmounted = false; - - function TestComponent() { - useEffect(() => { - return () => { - isUnmounted = true; - }; - }, []); - return <>Hello; - } - - renderAndTriggerHooks( - { - render(, element); - }} - nativeProps={{}} - />, - mountpoint - ); - - // Replaces the component at the mountpoint with nothing - renderAndTriggerHooks(<>Empty, mountpoint); - - expect(isUnmounted).toBe(true); - }); - - it('should handle when the mount function is asynchronous with a cleanup fn', async () => { - const unmountCallback = jest.fn(); - - renderAndTriggerHooks( - { - return unmountCallback; - }} - nativeProps={{}} - />, - mountpoint - ); - - // Schedule a promise cycle to update the DOM - await new Promise((resolve) => setTimeout(resolve, 0)); - - // Replaces the component at the mountpoint with nothing - renderAndTriggerHooks(<>Empty, mountpoint); - - expect(unmountCallback).toHaveBeenCalled(); - }); -}); diff --git a/x-pack/plugins/lens/public/native_renderer/native_renderer.tsx b/x-pack/plugins/lens/public/native_renderer/native_renderer.tsx deleted file mode 100644 index f0659a130b293..0000000000000 --- a/x-pack/plugins/lens/public/native_renderer/native_renderer.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { HTMLAttributes, useEffect, useRef } from 'react'; -import { unmountComponentAtNode } from 'react-dom'; - -type CleanupCallback = (el: Element) => void; - -export interface NativeRendererProps extends HTMLAttributes { - render: ( - domElement: Element, - props: T - ) => Promise | CleanupCallback | void; - nativeProps: T; - tag?: string; -} - -/** - * A component which takes care of providing a mountpoint for a generic render - * function which takes an html element and an optional props object. - * By default the mountpoint element will be a div, this can be changed with the - * `tag` prop. - * - * If the rendered component tree was using React, we need to clean it up manually, - * otherwise the unmount event never happens. A future addition is for non-React components - * to get cleaned up, which could be added in the future. - * - * @param props - */ -export function NativeRenderer({ render, nativeProps, tag, ...rest }: NativeRendererProps) { - const elementRef = useRef(); - const cleanupRef = useRef<((cleanupElement: Element) => void) | void>(); - useEffect(() => { - return () => { - if (elementRef.current) { - if (cleanupRef.current && typeof cleanupRef.current === 'function') { - cleanupRef.current(elementRef.current); - } - unmountComponentAtNode(elementRef.current); - } - }; - }, []); - return React.createElement(tag || 'div', { - ...rest, - ref: (el) => { - if (el) { - elementRef.current = el; - // Handles the editor frame renderer, which is async - const result = render(el, nativeProps); - if (result instanceof Promise) { - result.then((cleanup) => { - if (typeof cleanup === 'function') { - cleanupRef.current = cleanup; - } - }); - } else if (typeof result === 'function') { - cleanupRef.current = result; - } - } - }, - }); -} diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 042bdef118984..8ce305d967fe4 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -9,7 +9,7 @@ import type { IconType } from '@elastic/eui/src/components/icon/icon'; import type { CoreStart, SavedObjectReference, ResolvedSimpleSavedObject } from '@kbn/core/public'; import type { PaletteOutput } from '@kbn/coloring'; import type { TopNavMenuData } from '@kbn/navigation-plugin/public'; -import type { MutableRefObject } from 'react'; +import type { MutableRefObject, ReactElement } from 'react'; import type { Filter, TimeRange } from '@kbn/es-query'; import type { ExpressionAstExpression, @@ -40,12 +40,7 @@ import { estypes } from '@elastic/elasticsearch'; import React from 'react'; import { CellValueContext } from '@kbn/embeddable-plugin/public'; import { EventAnnotationGroupConfig } from '@kbn/event-annotation-plugin/common'; -import type { - DraggingIdentifier, - DragDropIdentifier, - DragContextValue, - DropType, -} from '@kbn/dom-drag-drop'; +import type { DraggingIdentifier, DragDropIdentifier, DropType } from '@kbn/dom-drag-drop'; import type { AccessorConfig } from '@kbn/visualization-ui-components/public'; import type { DateRange, LayerType, SortingHint } from '../common/types'; import type { @@ -372,26 +367,15 @@ export interface Datasource { }) => T; getSelectedFields?: (state: T) => string[]; - renderLayerSettings?: ( - domElement: Element, + LayerSettingsComponent?: ( props: DatasourceLayerSettingsProps - ) => ((cleanupElement: Element) => void) | void; - renderDataPanel: ( - domElement: Element, - props: DatasourceDataPanelProps - ) => ((cleanupElement: Element) => void) | void; - renderDimensionTrigger: ( - domElement: Element, - props: DatasourceDimensionTriggerProps - ) => ((cleanupElement: Element) => void) | void; - renderDimensionEditor: ( - domElement: Element, + ) => React.ReactElement> | null; + DataPanelComponent: (props: DatasourceDataPanelProps) => JSX.Element | null; + DimensionTriggerComponent: (props: DatasourceDimensionTriggerProps) => JSX.Element | null; + DimensionEditorComponent: ( props: DatasourceDimensionEditorProps - ) => ((cleanupElement: Element) => void) | void; - renderLayerPanel: ( - domElement: Element, - props: DatasourceLayerPanelProps - ) => ((cleanupElement: Element) => void) | void; + ) => ReactElement> | null; + LayerPanelComponent: (props: DatasourceLayerPanelProps) => JSX.Element | null; getDropProps: ( props: GetDropPropsArgs ) => { dropTypes: DropType[]; nextLabel?: string } | undefined; @@ -588,7 +572,6 @@ export interface DatasourceLayerSettingsProps { export interface DatasourceDataPanelProps { state: T; - dragDropContext: DragContextValue; setState: StateSetter; showNoDataPopover: () => void; core: Pick< @@ -1032,6 +1015,13 @@ export type RegisterLibraryAnnotationGroupFunction = (groupInfo: { id: string; group: EventAnnotationGroupConfig; }) => void; +interface AddLayerButtonProps { + supportedLayers: VisualizationLayerDescription[]; + addLayer: AddLayerFunction; + ensureIndexPattern: (specOrId: DataViewSpec | string) => Promise; + registerLibraryAnnotationGroup: RegisterLibraryAnnotationGroupFunction; +} + export interface Visualization { /** Plugin ID, such as "lnsXY" */ id: string; @@ -1161,27 +1151,24 @@ export interface Visualization - ) => ((cleanupElement: Element) => void) | void; + ) => null | ReactElement>; /** * Layer panel content rendered. This can be used to render a custom content below the title, * like a custom dataview switch */ - renderLayerPanel?: ( - domElement: Element, + LayerPanelComponent?: ( props: VisualizationLayerWidgetProps - ) => ((cleanupElement: Element) => void) | void; + ) => null | ReactElement>; /** * Toolbar rendered above the visualization. This is meant to be used to provide chart-level * settings for the visualization. */ - renderToolbar?: ( - domElement: Element, + ToolbarComponent?: ( props: VisualizationToolbarProps - ) => ((cleanupElement: Element) => void) | void; + ) => null | ReactElement>; /** * The frame is telling the visualization to update or set a dimension based on user interaction @@ -1216,49 +1203,42 @@ export interface Visualization) => Record<'data' | 'appearance', boolean>; - renderLayerSettings?: ( - domElement: Element, + LayerSettingsComponent?: ( props: VisualizationLayerSettingsProps & { section: 'data' | 'appearance' } - ) => ((cleanupElement: Element) => void) | void; + ) => null | ReactElement>; /** * Additional editor that gets rendered inside the dimension popover in the "appearance" section. * This can be used to configure dimension-specific options */ - renderDimensionEditor?: ( - domElement: Element, + DimensionEditorComponent?: ( props: VisualizationDimensionEditorProps - ) => ((cleanupElement: Element) => void) | void; + ) => null | ReactElement>; /** * Additional editor that gets rendered inside the dimension popover in an additional section below "appearance". * This can be used to configure dimension-specific options */ - renderDimensionEditorAdditionalSection?: ( - domElement: Element, + DimensionEditorAdditionalSectionComponent?: ( props: VisualizationDimensionEditorProps - ) => ((cleanupElement: Element) => void) | void; + ) => null | ReactElement>; /** * Additional editor that gets rendered inside the data section. * This can be used to configure dimension-specific options */ - renderDimensionEditorDataExtra?: ( - domElement: Element, + DimensionEditorDataExtraComponent?: ( props: VisualizationDimensionEditorProps - ) => ((cleanupElement: Element) => void) | void; + ) => null | ReactElement>; /** * Renders dimension trigger. Used only for noDatasource layers */ - renderDimensionTrigger?: (props: { + DimensionTriggerComponent?: (props: { columnId: string; label: string; hideTooltip?: boolean; - }) => JSX.Element | null; - getAddLayerButtonComponent?: (props: { - supportedLayers: VisualizationLayerDescription[]; - addLayer: AddLayerFunction; - ensureIndexPattern: (specOrId: DataViewSpec | string) => Promise; - registerLibraryAnnotationGroup: RegisterLibraryAnnotationGroupFunction; - }) => JSX.Element | null; + }) => null | ReactElement<{ columnId: string; label: string; hideTooltip?: boolean }>; + getAddLayerButtonComponent?: ( + props: AddLayerButtonProps + ) => null | ReactElement; /** * Creates map of columns ids and unique lables. Used only for noDatasource layers */ diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx index ecc6bc958124f..35757771af754 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx @@ -6,13 +6,10 @@ */ import React from 'react'; -import { render } from 'react-dom'; import { Ast } from '@kbn/interpreter'; -import { I18nProvider } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { PaletteRegistry, CUSTOM_PALETTE } from '@kbn/coloring'; import { ThemeServiceStart } from '@kbn/core/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { IconChartDatatable } from '@kbn/chart-icons'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; @@ -337,37 +334,16 @@ export const getDatatableVisualization = ({ sorting: prevState.sorting?.columnId === columnId ? undefined : prevState.sorting, }; }, - renderDimensionEditor(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorComponent(props) { + return ; }, - renderDimensionEditorAdditionalSection(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorAdditionalSectionComponent(props) { + return ; }, - renderDimensionEditorDataExtra(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorDataExtraComponent(props) { + return ; }, getSupportedLayers() { @@ -522,15 +498,8 @@ export const getDatatableVisualization = ({ }, []); }, - renderToolbar(domElement, props) { - render( - - - - - , - domElement - ); + ToolbarComponent(props) { + return ; }, onEditAction(state, event) { diff --git a/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx b/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx index ddab89444419f..b943e9601f24b 100644 --- a/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx @@ -6,11 +6,9 @@ */ import React from 'react'; -import { render } from 'react-dom'; import { i18n } from '@kbn/i18n'; import { ThemeServiceStart } from '@kbn/core/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; -import { FormattedMessage, I18nProvider } from '@kbn/i18n-react'; +import { FormattedMessage } from '@kbn/i18n-react'; import { Ast } from '@kbn/interpreter'; import { buildExpressionFunction, DatatableRow } from '@kbn/expressions-plugin/common'; import { PaletteRegistry, CustomPaletteParams, CUSTOM_PALETTE } from '@kbn/coloring'; @@ -400,26 +398,12 @@ export const getGaugeVisualization = ({ return update; }, - renderDimensionEditor(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorComponent(props) { + return ; }, - renderToolbar(domElement, props) { - render( - - - - - , - domElement - ); + ToolbarComponent(props) { + return ; }, getSupportedLayers(state, frame) { diff --git a/x-pack/plugins/lens/public/visualizations/heatmap/visualization.tsx b/x-pack/plugins/lens/public/visualizations/heatmap/visualization.tsx index 7d448e56e9fee..654d69284718c 100644 --- a/x-pack/plugins/lens/public/visualizations/heatmap/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/heatmap/visualization.tsx @@ -6,15 +6,13 @@ */ import React from 'react'; -import { render } from 'react-dom'; import { i18n } from '@kbn/i18n'; -import { FormattedMessage, I18nProvider } from '@kbn/i18n-react'; +import { FormattedMessage } from '@kbn/i18n-react'; import { Ast } from '@kbn/interpreter'; import { Position } from '@elastic/charts'; import { IconChartHeatmap } from '@kbn/chart-icons'; import { CUSTOM_PALETTE, PaletteRegistry, CustomPaletteParams } from '@kbn/coloring'; import { ThemeServiceStart } from '@kbn/core/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; import { HeatmapConfiguration } from '@kbn/visualizations-plugin/common'; @@ -272,26 +270,12 @@ export const getHeatmapVisualization = ({ return update; }, - renderDimensionEditor(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorComponent(props) { + return ; }, - renderToolbar(domElement, props) { - render( - - - - - , - domElement - ); + ToolbarComponent(props) { + return ; }, getSupportedLayers() { diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.tsx b/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.tsx index 85fea42623fc4..2f164ba3ed5b0 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/visualization.tsx @@ -5,13 +5,10 @@ * 2.0. */ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { I18nProvider } from '@kbn/i18n-react'; import { euiThemeVars } from '@kbn/ui-theme'; -import { render } from 'react-dom'; import { Ast } from '@kbn/interpreter'; import { PaletteOutput, PaletteRegistry, CUSTOM_PALETTE, shiftPalette } from '@kbn/coloring'; import { ThemeServiceStart } from '@kbn/core/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { ColorMode, CustomPaletteState } from '@kbn/charts-plugin/common'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { IconChartMetric } from '@kbn/chart-icons'; @@ -290,26 +287,12 @@ export const getLegacyMetricVisualization = ({ return { ...prevState, accessor: undefined, colorMode: ColorMode.None, palette: undefined }; }, - renderToolbar(domElement, props) { - render( - - - - - , - domElement - ); + ToolbarComponent(props) { + return ; }, - renderDimensionEditor(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorComponent(props) { + return ; }, getVisualizationInfo(state: LegacyMetricState) { diff --git a/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx b/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx index 4f18899a118df..b003174232125 100644 --- a/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx @@ -7,14 +7,11 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { I18nProvider } from '@kbn/i18n-react'; -import { render } from 'react-dom'; import { PaletteOutput, PaletteRegistry, CustomPaletteParams } from '@kbn/coloring'; import { ThemeServiceStart } from '@kbn/core/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { LayoutDirection } from '@elastic/charts'; import { euiLightVars, euiThemeVars } from '@kbn/ui-theme'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { IconChartMetric } from '@kbn/chart-icons'; import { AccessorConfig } from '@kbn/visualization-ui-components/public'; import { CollapseFunction } from '../../../common/expressions'; @@ -592,37 +589,16 @@ export const getMetricVisualization = ({ return updated; }, - renderToolbar(domElement, props) { - render( - - - - - , - domElement - ); + ToolbarComponent(props) { + return ; }, - renderDimensionEditor(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorComponent(props) { + return ; }, - renderDimensionEditorAdditionalSection(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorAdditionalSectionComponent(props) { + return ; }, getDisplayOptions() { diff --git a/x-pack/plugins/lens/public/visualizations/partition/visualization.tsx b/x-pack/plugins/lens/public/visualizations/partition/visualization.tsx index da4f275b49539..444342f08b723 100644 --- a/x-pack/plugins/lens/public/visualizations/partition/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/partition/visualization.tsx @@ -6,12 +6,10 @@ */ import React from 'react'; -import { render } from 'react-dom'; import { i18n } from '@kbn/i18n'; -import { FormattedMessage, I18nProvider } from '@kbn/i18n-react'; +import { FormattedMessage } from '@kbn/i18n-react'; import type { PaletteRegistry } from '@kbn/coloring'; import { ThemeServiceStart } from '@kbn/core/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { EuiSpacer } from '@elastic/eui'; import { PartitionVisConfiguration } from '@kbn/visualizations-plugin/common/convert_to_lens'; @@ -459,25 +457,11 @@ export const getPieVisualization = ({ layers: newState.layers.map((l) => (l.layerId === layerId ? newLayer : l)), }; }, - renderDimensionEditor(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorComponent(props) { + return ; }, - renderDimensionEditorDataExtra(domElement, props) { - render( - - - - - , - domElement - ); + DimensionEditorDataExtraComponent(props) { + return ; }, getSupportedLayers() { @@ -501,30 +485,16 @@ export const getPieVisualization = ({ toPreviewExpression: (state, layers, datasourceExpressionsByLayers) => toPreviewExpression(state, layers, paletteService, datasourceExpressionsByLayers), - renderToolbar(domElement, props) { - render( - - - - - , - domElement - ); + ToolbarComponent(props) { + return ; }, hasLayerSettings(props) { return { data: props.state.shape !== PieChartTypes.MOSAIC, appearance: false }; }, - renderLayerSettings(domElement, props) { - render( - - - - - , - domElement - ); + LayerSettingsComponent(props) { + return ; }, getSuggestionFromConvertToLensContext(props) { diff --git a/x-pack/plugins/lens/public/visualizations/tagcloud/tagcloud_visualization.tsx b/x-pack/plugins/lens/public/visualizations/tagcloud/tagcloud_visualization.tsx index 09e988b445795..d1bd1ec337bc0 100644 --- a/x-pack/plugins/lens/public/visualizations/tagcloud/tagcloud_visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/tagcloud/tagcloud_visualization.tsx @@ -7,10 +7,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { I18nProvider } from '@kbn/i18n-react'; -import { render } from 'react-dom'; import { ThemeServiceStart } from '@kbn/core/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import type { ExpressionTagcloudFunctionDefinition } from '@kbn/expression-tagcloud-plugin/common'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; @@ -268,31 +265,20 @@ export const getTagcloudVisualization = ({ return update; }, - renderDimensionEditor(domElement, props) { + DimensionEditorComponent(props) { if (props.groupId === TAG_GROUP_ID) { - render( - - - - - , - domElement + return ( + ); } + return null; }, - renderToolbar(domElement, props) { - render( - - - - - , - domElement - ); + ToolbarComponent(props) { + return ; }, }); diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx index 7d47cf9602415..d9f48f7b4d41b 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx @@ -6,9 +6,8 @@ */ import React from 'react'; -import { render } from 'react-dom'; import { Position } from '@elastic/charts'; -import { FormattedMessage, I18nProvider } from '@kbn/i18n-react'; +import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import type { PaletteRegistry } from '@kbn/coloring'; import { IconChartBarReferenceLine, IconChartBarAnnotations } from '@kbn/chart-icons'; @@ -18,7 +17,6 @@ import { EventAnnotationServiceType, getAnnotationAccessor, } from '@kbn/event-annotation-plugin/public'; -import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; @@ -340,15 +338,8 @@ export const getXyVisualization = ({ return { data: Boolean(layer && isAnnotationsLayer(layer)), appearance: false }; }, - renderLayerSettings(domElement, props) { - render( - - - - - , - domElement - ); + LayerSettingsComponent(props) { + return ; }, onIndexPatternChange(state, indexPatternId, layerId) { const layerIndex = state.layers.findIndex((l) => l.layerId === layerId); @@ -622,61 +613,29 @@ export const getXyVisualization = ({ }; }, - renderLayerPanel(domElement, props) { + LayerPanelComponent(props) { const { onChangeIndexPattern, ...otherProps } = props; - render( - - - - { - // TODO: should it trigger an action as in the datasource? - onChangeIndexPattern(indexPatternId); - }} - /> - - - , - domElement + + return ( + { + // TODO: should it trigger an action as in the datasource? + onChangeIndexPattern(indexPatternId); + }} + /> ); }, - renderLayerHeader(domElement, props) { - render( - - - - - , - domElement - ); + LayerHeaderComponent(props) { + return ; }, - renderToolbar(domElement, props) { - render( - - - - - , - domElement - ); + ToolbarComponent(props) { + return ; }, - renderDimensionEditor(domElement, props) { + DimensionEditorComponent(props) { const allProps = { ...props, datatableUtilities: data.datatableUtilities, @@ -692,31 +651,10 @@ export const getXyVisualization = ({ ); - render( - - - - {dimensionEditor} - - - , - domElement - ); + return dimensionEditor; }, - renderDimensionEditorDataExtra(domElement, props) { + DimensionEditorDataExtraComponent(props) { const allProps = { ...props, datatableUtilities: data.datatableUtilities, @@ -725,34 +663,13 @@ export const getXyVisualization = ({ }; const layer = props.state.layers.find((l) => l.layerId === props.layerId)!; if (isReferenceLayer(layer)) { - return; + return null; } if (isAnnotationsLayer(layer)) { - return; + return null; } - render( - - - - - - - , - domElement - ); + return ; }, getAddLayerButtonComponent: (props) => { return ( @@ -986,7 +903,7 @@ export const getXyVisualization = ({ state?.layers.filter(isAnnotationsLayer).map(({ indexPatternId }) => indexPatternId) ?? [] ); }, - renderDimensionTrigger({ columnId, label }) { + DimensionTriggerComponent({ columnId, label }) { if (label) { return ; } diff --git a/x-pack/plugins/maps/public/lens/choropleth_chart/visualization.tsx b/x-pack/plugins/maps/public/lens/choropleth_chart/visualization.tsx index 5018863acbc8d..81536846faf2c 100644 --- a/x-pack/plugins/maps/public/lens/choropleth_chart/visualization.tsx +++ b/x-pack/plugins/maps/public/lens/choropleth_chart/visualization.tsx @@ -7,12 +7,9 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { I18nProvider } from '@kbn/i18n-react'; -import { render } from 'react-dom'; import type { FileLayer } from '@elastic/ems-client'; import type { PaletteRegistry } from '@kbn/coloring'; import { ThemeServiceStart } from '@kbn/core/public'; -import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { layerTypes } from '@kbn/lens-plugin/public'; import type { OperationMetadata, SuggestionRequest, Visualization } from '@kbn/lens-plugin/public'; import { IconRegionMap } from '@kbn/chart-icons'; @@ -195,20 +192,16 @@ export const getVisualization = ({ return update; }, - renderDimensionEditor(domElement, props) { + DimensionEditorComponent(props) { if (props.groupId === REGION_KEY_GROUP_ID) { - render( - - - - - , - domElement + return ( + ); } + return null; }, }); From cdc862a6188e846e9e5f04bc1c98dadf6c04c0c1 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Tue, 11 Jul 2023 15:06:34 +0200 Subject: [PATCH 12/97] [Serverless] Allow authentication via the Elasticsearch JWT realm with the `shared_secret` client authentication type. (#161564) --- config/serverless.yml | 5 ++--- packages/kbn-es/src/settings.test.ts | 4 ++++ packages/kbn-es/src/settings.ts | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/config/serverless.yml b/config/serverless.yml index 6296173fbe94f..5f03bbb6de504 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -69,6 +69,5 @@ server.versioned.strictClientVersionCheck: false xpack.spaces.maxSpaces: 1 xpack.spaces.allowFeatureVisibility: false -# Temporarily allow unauthenticated access to task manager utilization & status/stats APIs for autoscaling -status.allowAnonymous: true -xpack.task_manager.unsafe.authenticate_background_task_utilization: false +# Allow authentication via the Elasticsearch JWT realm with the `shared_secret` client authentication type. +elasticsearch.requestHeadersWhitelist: ["authorization", "es-client-authentication"] diff --git a/packages/kbn-es/src/settings.test.ts b/packages/kbn-es/src/settings.test.ts index 6963c41e43f01..e8f0d05500299 100644 --- a/packages/kbn-es/src/settings.test.ts +++ b/packages/kbn-es/src/settings.test.ts @@ -12,6 +12,7 @@ const mockSettings = [ 'abc.def=1', 'xpack.security.authc.realms.oidc.oidc1.rp.client_secret=secret', 'xpack.security.authc.realms.oidc.oidc1.rp.client_id=client id', + 'xpack.security.authc.realms.jwt.jwt1.client_authentication.shared_secret=jwt_secret', 'discovery.type=single-node', ]; @@ -20,6 +21,7 @@ test('`parseSettings` parses and returns all settings by default', () => { ['abc.def', '1'], ['xpack.security.authc.realms.oidc.oidc1.rp.client_secret', 'secret'], ['xpack.security.authc.realms.oidc.oidc1.rp.client_id', 'client id'], + ['xpack.security.authc.realms.jwt.jwt1.client_authentication.shared_secret', 'jwt_secret'], ['discovery.type', 'single-node'], ]); }); @@ -29,6 +31,7 @@ test('`parseSettings` parses and returns all settings with `SettingsFilter.All` ['abc.def', '1'], ['xpack.security.authc.realms.oidc.oidc1.rp.client_secret', 'secret'], ['xpack.security.authc.realms.oidc.oidc1.rp.client_id', 'client id'], + ['xpack.security.authc.realms.jwt.jwt1.client_authentication.shared_secret', 'jwt_secret'], ['discovery.type', 'single-node'], ]); }); @@ -36,6 +39,7 @@ test('`parseSettings` parses and returns all settings with `SettingsFilter.All` test('`parseSettings` parses and returns only secure settings with `SettingsFilter.SecureOnly` filter', () => { expect(parseSettings(mockSettings, { filter: SettingsFilter.SecureOnly })).toEqual([ ['xpack.security.authc.realms.oidc.oidc1.rp.client_secret', 'secret'], + ['xpack.security.authc.realms.jwt.jwt1.client_authentication.shared_secret', 'jwt_secret'], ]); }); diff --git a/packages/kbn-es/src/settings.ts b/packages/kbn-es/src/settings.ts index a5919dccebd5a..dabc7482a75be 100644 --- a/packages/kbn-es/src/settings.ts +++ b/packages/kbn-es/src/settings.ts @@ -11,6 +11,7 @@ */ const SECURE_SETTINGS_LIST = [ /^xpack\.security\.authc\.realms\.oidc\.[a-zA-Z0-9_]+\.rp\.client_secret$/, + /^xpack\.security\.authc\.realms\.jwt\.[a-zA-Z0-9_]+\.client_authentication\.shared_secret$/, ]; function isSecureSetting(settingName: string) { From a5627bec5781575c02dec671f2635eaab8bc4f40 Mon Sep 17 00:00:00 2001 From: Dmitrii Shevchenko Date: Tue, 11 Jul 2023 15:07:35 +0200 Subject: [PATCH 13/97] [Security Solution] Fix endpoint permissions for rule installation and update (#161641) **Related to: https://github.com/elastic/kibana/issues/161443, https://github.com/elastic/kibana/pull/161454** ## Summary The `access:securitySolution-all` access level prevents a properly configured role from installing or updating detection rules. This PR aligns the access level for the `installation/_perform` and `upgrade/_perform` endpoints with the rest of the detection engine APIs. ### Test instructions Configure a role with the following permissions: ```json { "test": { "cluster": [], "indices": [ { "names": [ ".alerts-security.alerts-default", ".lists-default", ".items-default" ], "privileges": [ "read", "write", "view_index_metadata", "maintenance" ], "field_security": { "grant": [ "*" ] }, "allow_restricted_indices": false } ], "applications": [ { "application": "kibana-.kibana", "privileges": [ "feature_siem.all" ], "resources": [ "*" ] } ], "run_as": [], "metadata": {}, "transient_metadata": { "enabled": true } } } ``` Call the upgrade/install APIs on behalf of that role to see that no 403 is returned: ```sh curl --location 'http://localhost:5601/kbn/internal/detection_engine/prebuilt_rules/installation/_perform' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "mode": "ALL_RULES" }' curl --location 'http://localhost:5601/kbn/internal/detection_engine/prebuilt_rules/upgrade/_perform' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{ "mode": "ALL_RULES" }' ``` --- .../perform_rule_installation_route.ts | 2 +- .../api/perform_rule_upgrade/perform_rule_upgrade_route.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts index 0aac5f196ec95..ba7ca335402e7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_installation/perform_rule_installation_route.ts @@ -35,7 +35,7 @@ export const performRuleInstallationRoute = (router: SecuritySolutionPluginRoute body: buildRouteValidation(PerformRuleInstallationRequestBody), }, options: { - tags: ['access:securitySolution-all'], + tags: ['access:securitySolution'], }, }, async (context, request, response) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts index 6197127e9d923..47f90cf5fb427 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/perform_rule_upgrade/perform_rule_upgrade_route.ts @@ -39,7 +39,7 @@ export const performRuleUpgradeRoute = (router: SecuritySolutionPluginRouter) => body: buildRouteValidation(PerformRuleUpgradeRequestBody), }, options: { - tags: ['access:securitySolution-all'], + tags: ['access:securitySolution'], }, }, async (context, request, response) => { From 672c90a9c126b91b8a94ab9a38fdf5c308593dd0 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 11 Jul 2023 16:22:57 +0300 Subject: [PATCH 14/97] [Dashboard] Panel settings action improvements (#161616) ## Summary Part of https://github.com/elastic/kibana/issues/160256 - Replaces the Edit panel settings text with the simpler Panel settings - Replaces the documentation - Replaces the icon image ### Checklist - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials --- docs/user/canvas.asciidoc | 2 +- docs/user/dashboard/dashboard.asciidoc | 4 ++-- .../tutorial-create-a-dashboard-of-lens-panels.asciidoc | 8 ++++---- .../customize_panel/customize_panel_action.tsx | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/user/canvas.asciidoc b/docs/user/canvas.asciidoc index be69c0236cd50..fd11a1162176f 100644 --- a/docs/user/canvas.asciidoc +++ b/docs/user/canvas.asciidoc @@ -139,7 +139,7 @@ Add a panel that you saved in *Visualize Library* to your workpad. * *Edit Visualization* — Opens the visualization editor so that you can edit the panel. -* *Edit panel settings* — Allows you to change the title, description, and time range for the panel. +* *Panel settings* — Allows you to change the title, description, and time range for the panel. * *Inspect* — Allows you to drill down into the panel data. diff --git a/docs/user/dashboard/dashboard.asciidoc b/docs/user/dashboard/dashboard.asciidoc index 5da14bc58572d..948c487485db4 100644 --- a/docs/user/dashboard/dashboard.asciidoc +++ b/docs/user/dashboard/dashboard.asciidoc @@ -295,7 +295,7 @@ To make changes without changing the original version, open the panel menu, then * *Convert to Lens* — Opens *TSVB* and aggregation-based visualizations in *Lens*. -* *Edit panel settings* — Opens the *Panel settings* window to change the *title*, *description*, and *time range*. +* *Panel settings* — Opens the *Panel settings* window to change the *title*, *description*, and *time range*. * *More > Replace panel* — Opens the *Visualize Library* so you can select a new panel to replace the existing panel. @@ -391,7 +391,7 @@ For more information about {kib} and {es} filters, refer to < Edit panel settings*. +. Open the panel menu, then select *More > Panel settings*. . Select *Apply a custom time range*. diff --git a/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc b/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc index 18b2b0a148154..ecc7b49750eed 100644 --- a/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc +++ b/docs/user/dashboard/tutorial-create-a-dashboard-of-lens-panels.asciidoc @@ -141,7 +141,7 @@ image::images/lens_lineChartMetricOverTimeBottomAxis_8.7.png[Bottom axis menu] Since you removed the axis labels, add a panel title: -. Open the panel menu, then select *Edit panel settings*. +. Open the panel menu, then select *Panel settings*. . In the *Title* field, enter `Median of bytes`, then click *Save*. + @@ -245,7 +245,7 @@ image::images/lens_pieChartCompareSubsetOfDocs_7.16.png[Pie chart that compares Add a panel title: -. Open the panel menu, then select *Edit panel settings*. +. Open the panel menu, then select *Panel settings*. . In the *Title* field, enter `Sum of bytes from large requests`, then click *Save*. @@ -278,7 +278,7 @@ image::images/lens_barChartDistributionOfNumberField_7.16.png[Bar chart that dis Add a panel title: -. Open the panel menu, then select *Edit panel settings*. +. Open the panel menu, then select *Panel settings*. . In the *Title* field, enter `Website traffic`, then click *Save*. @@ -342,7 +342,7 @@ image::images/lens_treemapMultiLevelChart_7.16.png[Treemap visualization] Add a panel title: -. Open the panel menu, then select *Edit panel settings*. +. Open the panel menu, then select *Panel settings*. . In the *Title* field, enter `Page views by location and referrer`, then click *Save*. diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_panel/customize_panel_action.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_panel/customize_panel_action.tsx index fc7a30efbe256..6146199eee24b 100644 --- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_panel/customize_panel_action.tsx +++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_panel/customize_panel_action.tsx @@ -87,12 +87,12 @@ export class CustomizePanelAction implements Action public getDisplayName({ embeddable }: CustomizePanelActionContext): string { return i18n.translate('embeddableApi.customizePanel.action.displayName', { - defaultMessage: 'Edit panel settings', + defaultMessage: 'Panel settings', }); } public getIconType() { - return 'pencil'; + return 'gear'; } public async isCompatible({ embeddable }: CustomizePanelActionContext) { From d9d1404119cc4de719eafc98a73716554f4e573b Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Tue, 11 Jul 2023 08:23:46 -0500 Subject: [PATCH 15/97] [saved search] Remove saved object client from data views plugin for saved search usage (#159109) ## Summary Previously the data plugin relied on the data view plugin to load saved searches since the saved searches depend upon the data plugin and circular dependencies needed to be avoided. This is innovative and perhaps a bit crazy. What this PR does - Data view api no longer loads saved searches, removing browser saved object client usage - Moves `kibana_context` expression and getKibanaContext function from data plugin to saved search plugin since it loads saved searches - Rename data views `SavedObjectsClientCommon` to `PersistenceAPI` - this is the abstraction around saved object loading that no longer is exclusive to the saved objects api. - Adds saved search server api (plugin contract) for loading saved searches. - Functional tests on browser and server for kibana_context expression when loading saved searches --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../search/expressions/kibana_context.ts | 143 +----------------- .../search/expressions/kibana_context_type.ts | 30 +--- .../data/public/search/search_service.ts | 9 +- .../data/server/search/search_service.ts | 5 +- src/plugins/data/tsconfig.json | 2 +- .../common/data_views/data_views.test.ts | 10 +- .../common/data_views/data_views.ts | 6 +- src/plugins/data_views/common/index.ts | 2 +- src/plugins/data_views/common/types.ts | 12 +- src/plugins/data_views/common/utils.ts | 4 +- ....ts => content_management_wrapper.test.ts} | 12 +- ...apper.ts => content_management_wrapper.ts} | 20 +-- src/plugins/data_views/public/index.ts | 3 +- src/plugins/data_views/public/plugin.ts | 9 +- .../server/data_views_service_factory.ts | 4 +- src/plugins/data_views/server/index.ts | 2 +- .../saved_objects_client_wrapper.test.ts | 8 +- .../server/saved_objects_client_wrapper.ts | 4 +- .../saved_search/common/expressions/index.ts | 9 ++ .../expressions/kibana_context.test.ts | 46 +++--- .../common/expressions/kibana_context.ts | 139 +++++++++++++++++ .../common/expressions/kibana_context_type.ts | 36 +++++ src/plugins/saved_search/common/index.ts | 1 + .../service}/get_saved_searches.test.ts | 39 +++-- .../service}/get_saved_searches.ts | 43 +++--- .../service}/saved_searches_utils.test.ts | 3 +- .../service}/saved_searches_utils.ts | 7 +- src/plugins/saved_search/common/types.ts | 7 + src/plugins/saved_search/kibana.jsonc | 3 +- .../public}/expressions/kibana_context.ts | 17 ++- src/plugins/saved_search/public/plugin.ts | 22 ++- .../public/services/saved_searches/index.ts | 7 +- .../saved_searches/save_saved_searches.ts | 2 +- .../saved_searches/saved_searches_service.ts | 12 +- .../server}/expressions/kibana_context.ts | 37 +++-- src/plugins/saved_search/server/plugin.ts | 49 ++++-- src/plugins/saved_search/tsconfig.json | 3 + .../fixtures/kbn_archiver/saved_search.json | 27 ++++ .../test_suites/run_pipeline/esaggs.ts | 38 +++++ .../jobs/new_job/utils/new_job_utils.test.ts | 12 +- .../translations/translations/fr-FR.json | 10 +- .../translations/translations/ja-JP.json | 10 +- .../translations/translations/zh-CN.json | 10 +- 43 files changed, 502 insertions(+), 372 deletions(-) rename src/plugins/data_views/public/{saved_objects_client_wrapper.test.ts => content_management_wrapper.test.ts} (75%) rename src/plugins/data_views/public/{saved_objects_client_wrapper.ts => content_management_wrapper.ts} (82%) create mode 100644 src/plugins/saved_search/common/expressions/index.ts rename src/plugins/{data/common/search => saved_search/common}/expressions/kibana_context.test.ts (87%) create mode 100644 src/plugins/saved_search/common/expressions/kibana_context.ts create mode 100644 src/plugins/saved_search/common/expressions/kibana_context_type.ts rename src/plugins/saved_search/{public/services/saved_searches => common/service}/get_saved_searches.test.ts (91%) rename src/plugins/saved_search/{public/services/saved_searches => common/service}/get_saved_searches.ts (65%) rename src/plugins/saved_search/{public/services/saved_searches => common/service}/saved_searches_utils.test.ts (97%) rename src/plugins/saved_search/{public/services/saved_searches => common/service}/saved_searches_utils.ts (92%) rename src/plugins/{data/public/search => saved_search/public}/expressions/kibana_context.ts (71%) rename src/plugins/{data/server/search => saved_search/server}/expressions/kibana_context.ts (53%) create mode 100644 test/functional/fixtures/kbn_archiver/saved_search.json diff --git a/src/plugins/data/common/search/expressions/kibana_context.ts b/src/plugins/data/common/search/expressions/kibana_context.ts index 4fa07676c0152..9f9a7f274ab5b 100644 --- a/src/plugins/data/common/search/expressions/kibana_context.ts +++ b/src/plugins/data/common/search/expressions/kibana_context.ts @@ -6,22 +6,15 @@ * Side Public License, v 1. */ -import { isEqual, uniqBy } from 'lodash'; -import { i18n } from '@kbn/i18n'; import { ExpressionFunctionDefinition, ExecutionContext } from '@kbn/expressions-plugin/common'; import { Adapters } from '@kbn/inspector-plugin/common'; -import { Filter, fromCombinedFilter } from '@kbn/es-query'; -import { Query, uniqFilters } from '@kbn/es-query'; -import { unboxExpressionValue } from '@kbn/expressions-plugin/common'; -import { SavedObjectReference } from '@kbn/core/types'; -import { SavedObjectsClientCommon } from '@kbn/data-views-plugin/common'; -import { ExecutionContextSearch, KibanaContext, KibanaFilter } from './kibana_context_type'; -import { KibanaQueryOutput } from './kibana_context_type'; -import { KibanaTimerangeOutput } from './timerange'; - -export interface KibanaContextStartDependencies { - savedObjectsClient: SavedObjectsClientCommon; -} +import { + KibanaTimerangeOutput, + ExecutionContextSearch, + KibanaContext, + KibanaFilter, + KibanaQueryOutput, +} from '../..'; interface Arguments { q?: KibanaQueryOutput[] | null; @@ -37,125 +30,3 @@ export type ExpressionFunctionKibanaContext = ExpressionFunctionDefinition< Promise, ExecutionContext >; - -const getParsedValue = (data: any, defaultValue: any) => - typeof data === 'string' && data.length ? JSON.parse(data) || defaultValue : defaultValue; - -const mergeQueries = (first: Query | Query[] = [], second: Query | Query[]) => - uniqBy( - [...(Array.isArray(first) ? first : [first]), ...(Array.isArray(second) ? second : [second])], - (n: any) => JSON.stringify(n.query) - ); - -export const getKibanaContextFn = ( - getStartDependencies: ( - getKibanaRequest: ExecutionContext['getKibanaRequest'] - ) => Promise -) => { - const kibanaContextFunction: ExpressionFunctionKibanaContext = { - name: 'kibana_context', - type: 'kibana_context', - inputTypes: ['kibana_context', 'null'], - help: i18n.translate('data.search.functions.kibana_context.help', { - defaultMessage: 'Updates kibana global context', - }), - args: { - q: { - types: ['kibana_query', 'null'], - multi: true, - aliases: ['query', '_'], - help: i18n.translate('data.search.functions.kibana_context.q.help', { - defaultMessage: 'Specify Kibana free form text query', - }), - }, - filters: { - types: ['kibana_filter', 'null'], - multi: true, - help: i18n.translate('data.search.functions.kibana_context.filters.help', { - defaultMessage: 'Specify Kibana generic filters', - }), - }, - timeRange: { - types: ['timerange', 'null'], - default: null, - help: i18n.translate('data.search.functions.kibana_context.timeRange.help', { - defaultMessage: 'Specify Kibana time range filter', - }), - }, - savedSearchId: { - types: ['string', 'null'], - default: null, - help: i18n.translate('data.search.functions.kibana_context.savedSearchId.help', { - defaultMessage: 'Specify saved search ID to be used for queries and filters', - }), - }, - }, - - extract(state) { - const references: SavedObjectReference[] = []; - if (state.savedSearchId.length && typeof state.savedSearchId[0] === 'string') { - const refName = 'kibana_context.savedSearchId'; - references.push({ - name: refName, - type: 'search', - id: state.savedSearchId[0] as string, - }); - return { - state: { - ...state, - savedSearchId: [refName], - }, - references, - }; - } - return { state, references }; - }, - - inject(state, references) { - const reference = references.find((r) => r.name === 'kibana_context.savedSearchId'); - if (reference) { - state.savedSearchId[0] = reference.id; - } - return state; - }, - - async fn(input, args, { getKibanaRequest }) { - const { savedObjectsClient } = await getStartDependencies(getKibanaRequest); - - const timeRange = args.timeRange || input?.timeRange; - let queries = mergeQueries(input?.query, args?.q?.filter(Boolean) || []); - const filterFromArgs = (args?.filters?.map(unboxExpressionValue) || []) as Filter[]; - - let filters = [...(input?.filters || [])]; - - if (args.savedSearchId) { - const obj = await savedObjectsClient.getSavedSearch(args.savedSearchId); - const search = (obj.attributes as any).kibanaSavedObjectMeta.searchSourceJSON as string; - const { query, filter } = getParsedValue(search, {}); - - if (query) { - queries = mergeQueries(queries, query); - } - if (filter) { - filters = [...filters, ...(Array.isArray(filter) ? filter : [filter])]; - } - } - const uniqueArgFilters = filterFromArgs.filter( - (argF) => - !filters.some((f) => { - return isEqual(fromCombinedFilter(f).query, argF.query); - }) - ); - - filters = [...filters, ...uniqueArgFilters]; - - return { - type: 'kibana_context', - query: queries, - filters: uniqFilters(filters.filter((f: any) => !f.meta?.disabled)), - timeRange, - }; - }, - }; - return kibanaContextFunction; -}; diff --git a/src/plugins/data/common/search/expressions/kibana_context_type.ts b/src/plugins/data/common/search/expressions/kibana_context_type.ts index 10db5b170ce85..cec788d27d856 100644 --- a/src/plugins/data/common/search/expressions/kibana_context_type.ts +++ b/src/plugins/data/common/search/expressions/kibana_context_type.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ import { Filter } from '@kbn/es-query'; -import { ExpressionValueBoxed, ExpressionValueFilter } from '@kbn/expressions-plugin/common'; +import { ExpressionValueBoxed } from '@kbn/expressions-plugin/common'; import { Query, TimeRange } from '../../query'; -import { adaptToExpressionValueFilter, DataViewField } from '../..'; +import { DataViewField } from '../..'; // eslint-disable-next-line @typescript-eslint/consistent-type-definitions export type ExecutionContextSearch = { @@ -30,29 +30,3 @@ export type KibanaField = ExpressionValueBoxed<'kibana_field', DataViewField>; // TODO: These two are exported for legacy reasons - remove them eventually. export type KIBANA_CONTEXT_NAME = 'kibana_context'; export type KibanaContext = ExpressionValueSearchContext; - -export const kibanaContext = { - name: 'kibana_context', - from: { - null: () => { - return { - type: 'kibana_context', - }; - }, - }, - to: { - null: () => { - return { - type: 'null', - }; - }, - filter: (input: KibanaContext): ExpressionValueFilter => { - const { filters = [] } = input; - return { - type: 'filter', - filterType: 'filter', - and: filters.map(adaptToExpressionValueFilter), - }; - }, - }, -}; diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index c4a135b64ca94..d9033e0eed5f1 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -38,7 +38,6 @@ import { ipRangeFunction, ISearchGeneric, kibana, - kibanaContext, kibanaFilterFunction, kibanaTimerangeFunction, kqlFunction, @@ -65,7 +64,7 @@ import { DataPublicPluginStart, DataStartDependencies } from '../types'; import { AggsService } from './aggs'; import { createUsageCollector, SearchUsageCollector } from './collectors'; import { getEql, getEsaggs, getEsdsl, getEssql } from './expressions'; -import { getKibanaContext } from './expressions/kibana_context'; + import { handleWarnings } from './fetch/handle_warnings'; import { ISearchInterceptor, SearchInterceptor } from './search_interceptor'; import { ISessionsClient, ISessionService, SessionsClient, SessionService } from './session'; @@ -143,11 +142,6 @@ export class SearchService implements Plugin { }) ); expressions.registerFunction(kibana); - expressions.registerFunction( - getKibanaContext({ getStartServices } as { - getStartServices: StartServicesAccessor; - }) - ); expressions.registerFunction(cidrFunction); expressions.registerFunction(dateRangeFunction); expressions.registerFunction(extendedBoundsFunction); @@ -167,7 +161,6 @@ export class SearchService implements Plugin { expressions.registerFunction(removeFilterFunction); expressions.registerFunction(selectFilterFunction); expressions.registerFunction(phraseFilterFunction); - expressions.registerType(kibanaContext); expressions.registerFunction( getEsdsl({ getStartServices } as { diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index 8189177c4b58b..f9d1c79390fb5 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -67,7 +67,6 @@ import { ipRangeFunction, ISearchOptions, kibana, - kibanaContext, kibanaFilterFunction, kibanaTimerangeFunction, kqlFunction, @@ -94,7 +93,6 @@ import { aggShardDelay } from '../../common/search/aggs/buckets/shard_delay_fn'; import { ConfigSchema } from '../../config'; import { SearchSessionService } from './session'; import { registerBsearchRoute } from './routes/bsearch'; -import { getKibanaContext } from './expressions/kibana_context'; import { enhancedEsSearchStrategyProvider } from './strategies/ese_search'; import { eqlSearchStrategyProvider } from './strategies/eql_search'; import { NoSearchIdInSessionError } from './errors/no_search_id_in_session'; @@ -233,7 +231,6 @@ export class SearchService implements Plugin { expressions.registerFunction(luceneFunction); expressions.registerFunction(kqlFunction); expressions.registerFunction(kibanaTimerangeFunction); - expressions.registerFunction(getKibanaContext({ getStartServices: core.getStartServices })); expressions.registerFunction(fieldFunction); expressions.registerFunction(numericalRangeFunction); expressions.registerFunction(rangeFunction); @@ -244,7 +241,7 @@ export class SearchService implements Plugin { expressions.registerFunction(removeFilterFunction); expressions.registerFunction(selectFilterFunction); expressions.registerFunction(phraseFilterFunction); - expressions.registerType(kibanaContext); + expressions.registerType(esRawResponse); expressions.registerType(eqlRawResponse); diff --git a/src/plugins/data/tsconfig.json b/src/plugins/data/tsconfig.json index d98f0da445171..450c858265917 100644 --- a/src/plugins/data/tsconfig.json +++ b/src/plugins/data/tsconfig.json @@ -49,7 +49,7 @@ "@kbn/core-application-browser", "@kbn/core-saved-objects-server", "@kbn/core-saved-objects-utils-server", - "@kbn/data-service", + "@kbn/data-service" ], "exclude": [ "target/**/*", diff --git a/src/plugins/data_views/common/data_views/data_views.test.ts b/src/plugins/data_views/common/data_views/data_views.test.ts index ec3d9acb8aaf0..e6d09710fe016 100644 --- a/src/plugins/data_views/common/data_views/data_views.test.ts +++ b/src/plugins/data_views/common/data_views/data_views.test.ts @@ -13,7 +13,7 @@ import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks'; import { UiSettingsCommon, - SavedObjectsClientCommon, + PersistenceAPI, SavedObject, DataViewSpec, IDataViewsApiClient, @@ -60,7 +60,7 @@ const savedObject = { describe('IndexPatterns', () => { let indexPatterns: DataViewsService; let indexPatternsNoAccess: DataViewsService; - let savedObjectsClient: SavedObjectsClientCommon; + let savedObjectsClient: PersistenceAPI; let SOClientGetDelay = 0; let apiClient: IDataViewsApiClient; const uiSettings = { @@ -73,7 +73,7 @@ describe('IndexPatterns', () => { beforeEach(() => { jest.clearAllMocks(); - savedObjectsClient = {} as SavedObjectsClientCommon; + savedObjectsClient = {} as PersistenceAPI; savedObjectsClient.find = jest.fn( () => Promise.resolve([indexPatternObj]) as Promise>> ); @@ -107,7 +107,7 @@ describe('IndexPatterns', () => { indexPatterns = new DataViewsService({ uiSettings, - savedObjectsClient: savedObjectsClient as unknown as SavedObjectsClientCommon, + savedObjectsClient: savedObjectsClient as unknown as PersistenceAPI, apiClient, fieldFormats, onNotification: () => {}, @@ -119,7 +119,7 @@ describe('IndexPatterns', () => { indexPatternsNoAccess = new DataViewsService({ uiSettings, - savedObjectsClient: savedObjectsClient as unknown as SavedObjectsClientCommon, + savedObjectsClient: savedObjectsClient as unknown as PersistenceAPI, apiClient, fieldFormats, onNotification: () => {}, diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts index f51189f2409ea..469fd2a1fa61e 100644 --- a/src/plugins/data_views/common/data_views/data_views.ts +++ b/src/plugins/data_views/common/data_views/data_views.ts @@ -11,7 +11,7 @@ import type { PublicMethodsOf } from '@kbn/utility-types'; import { castEsToKbnFieldTypeName } from '@kbn/field-types'; import { FieldFormatsStartCommon, FORMATS_UI_SETTINGS } from '@kbn/field-formats-plugin/common'; import { v4 as uuidv4 } from 'uuid'; -import { SavedObjectsClientCommon } from '../types'; +import { PersistenceAPI } from '../types'; import { createDataViewCache } from '.'; import type { RuntimeField, RuntimeFieldSpec, RuntimeType } from '../types'; @@ -89,7 +89,7 @@ export interface DataViewsServiceDeps { /** * Saved objects client interface wrapped in a common interface */ - savedObjectsClient: SavedObjectsClientCommon; + savedObjectsClient: PersistenceAPI; /** * Wrapper around http call functionality so it can be used on client or server */ @@ -292,7 +292,7 @@ export interface DataViewsServicePublicMethods { */ export class DataViewsService { private config: UiSettingsCommon; - private savedObjectsClient: SavedObjectsClientCommon; + private savedObjectsClient: PersistenceAPI; private savedObjectsCache?: Array> | null; private apiClient: IDataViewsApiClient; private fieldFormats: FieldFormatsStartCommon; diff --git a/src/plugins/data_views/common/index.ts b/src/plugins/data_views/common/index.ts index de167a17c0eca..32b88d48a9798 100644 --- a/src/plugins/data_views/common/index.ts +++ b/src/plugins/data_views/common/index.ts @@ -38,7 +38,7 @@ export type { OnNotification, OnError, UiSettingsCommon, - SavedObjectsClientCommon, + PersistenceAPI, GetFieldsOptions, IDataViewsApiClient, SavedObject, diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts index aa157d5336685..8e4c42d27b2f8 100644 --- a/src/plugins/data_views/common/types.ts +++ b/src/plugins/data_views/common/types.ts @@ -252,10 +252,10 @@ export interface SavedObjectsClientCommonFindArgs { } /** - * Common interface for the saved objects client + * Common interface for the saved objects client on server and content management in browser * @public */ -export interface SavedObjectsClientCommon { +export interface PersistenceAPI { /** * Search for saved objects * @param options - options for search @@ -269,14 +269,6 @@ export interface SavedObjectsClientCommon { * @param id - id of saved object */ get: (id: string) => Promise>; - /** - * Update a saved object by id - * @param type - type of saved object - * @param id - id of saved object - * @param attributes - attributes to update - * @param options - client options - */ - getSavedSearch: (id: string) => Promise; /** * Update a saved object by id * @param type - type of saved object diff --git a/src/plugins/data_views/common/utils.ts b/src/plugins/data_views/common/utils.ts index 05822ed363e9f..e63167ff4d3ff 100644 --- a/src/plugins/data_views/common/utils.ts +++ b/src/plugins/data_views/common/utils.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import type { SavedObjectsClientCommon } from './types'; +import type { PersistenceAPI } from './types'; /** * Returns an object matching a given name @@ -15,7 +15,7 @@ import type { SavedObjectsClientCommon } from './types'; * @param name {string} * @returns {SavedObject|undefined} */ -export async function findByName(client: SavedObjectsClientCommon, name: string) { +export async function findByName(client: PersistenceAPI, name: string) { if (name) { const savedObjects = await client.find({ perPage: 10, diff --git a/src/plugins/data_views/public/saved_objects_client_wrapper.test.ts b/src/plugins/data_views/public/content_management_wrapper.test.ts similarity index 75% rename from src/plugins/data_views/public/saved_objects_client_wrapper.test.ts rename to src/plugins/data_views/public/content_management_wrapper.test.ts index 898d22b7d3637..aefbd715fe780 100644 --- a/src/plugins/data_views/public/saved_objects_client_wrapper.test.ts +++ b/src/plugins/data_views/public/content_management_wrapper.test.ts @@ -6,13 +6,11 @@ * Side Public License, v 1. */ -import { SavedObjectsClientPublicToCommon } from './saved_objects_client_wrapper'; +import { ContentMagementWrapper } from './content_management_wrapper'; import { ContentClient } from '@kbn/content-management-plugin/public'; -import { savedObjectsServiceMock } from '@kbn/core/public/mocks'; import { DataViewSavedObjectConflictError } from '../common'; -describe('SavedObjectsClientPublicToCommon', () => { - const soClient = savedObjectsServiceMock.createStartContract().client; +describe('ContentMagementWrapper', () => { const cmClient = {} as ContentClient; test('get saved object - exactMatch', async () => { @@ -22,7 +20,7 @@ describe('SavedObjectsClientPublicToCommon', () => { cmClient.get = jest .fn() .mockResolvedValue({ meta: { outcome: 'exactMatch' }, item: mockedSavedObject }); - const service = new SavedObjectsClientPublicToCommon(cmClient, soClient); + const service = new ContentMagementWrapper(cmClient); const result = await service.get('1'); expect(result).toStrictEqual(mockedSavedObject); }); @@ -34,7 +32,7 @@ describe('SavedObjectsClientPublicToCommon', () => { cmClient.get = jest .fn() .mockResolvedValue({ meta: { outcome: 'aliasMatch' }, item: mockedSavedObject }); - const service = new SavedObjectsClientPublicToCommon(cmClient, soClient); + const service = new ContentMagementWrapper(cmClient); const result = await service.get('1'); expect(result).toStrictEqual(mockedSavedObject); }); @@ -47,7 +45,7 @@ describe('SavedObjectsClientPublicToCommon', () => { cmClient.get = jest .fn() .mockResolvedValue({ meta: { outcome: 'conflict' }, item: mockedSavedObject }); - const service = new SavedObjectsClientPublicToCommon(cmClient, soClient); + const service = new ContentMagementWrapper(cmClient); await expect(service.get('1')).rejects.toThrow(DataViewSavedObjectConflictError); }); diff --git a/src/plugins/data_views/public/saved_objects_client_wrapper.ts b/src/plugins/data_views/public/content_management_wrapper.ts similarity index 82% rename from src/plugins/data_views/public/saved_objects_client_wrapper.ts rename to src/plugins/data_views/public/content_management_wrapper.ts index 2e22ef889b1ac..d4fde29103999 100644 --- a/src/plugins/data_views/public/saved_objects_client_wrapper.ts +++ b/src/plugins/data_views/public/content_management_wrapper.ts @@ -8,12 +8,11 @@ import type { ContentClient } from '@kbn/content-management-plugin/public'; import { SavedObjectNotFound } from '@kbn/kibana-utils-plugin/common'; -import type { SavedObjectsClientContract } from '@kbn/core/public'; import { DataViewSavedObjectConflictError } from '../common/errors'; import { DataViewAttributes, SavedObject, - SavedObjectsClientCommon, + PersistenceAPI, SavedObjectsClientCommonFindArgs, } from '../common/types'; @@ -21,15 +20,11 @@ import type { DataViewCrudTypes } from '../common/content_management'; import { DataViewSOType } from '../common/content_management'; -type SOClient = Pick; - -export class SavedObjectsClientPublicToCommon implements SavedObjectsClientCommon { +export class ContentMagementWrapper implements PersistenceAPI { private contentManagementClient: ContentClient; - private savedObjectClient: SOClient; - constructor(contentManagementClient: ContentClient, savedObjectClient: SOClient) { + constructor(contentManagementClient: ContentClient) { this.contentManagementClient = contentManagementClient; - this.savedObjectClient = savedObjectClient; } async find(options: SavedObjectsClientCommonFindArgs) { @@ -75,15 +70,6 @@ export class SavedObjectsClientPublicToCommon implements SavedObjectsClientCommo return response.item; } - async getSavedSearch(id: string) { - const response = await this.savedObjectClient.resolve('search', id); - - if (response.outcome === 'conflict') { - throw new DataViewSavedObjectConflictError(id); - } - return response.saved_object; - } - async update( id: string, attributes: DataViewAttributes, diff --git a/src/plugins/data_views/public/index.ts b/src/plugins/data_views/public/index.ts index 8ee149622f39f..777e386189d62 100644 --- a/src/plugins/data_views/public/index.ts +++ b/src/plugins/data_views/public/index.ts @@ -19,7 +19,7 @@ export type { DataViewSpec, FieldSpec, DataViewAttributes, - SavedObjectsClientCommon, + PersistenceAPI, RuntimeField, } from '../common'; export { @@ -48,7 +48,6 @@ export type { export { DataViewsApiClient, DataViewsService, DataView } from './data_views'; export type { DataViewListItem } from './data_views'; export { UiSettingsPublicToCommon } from './ui_settings_wrapper'; -export { SavedObjectsClientPublicToCommon } from './saved_objects_client_wrapper'; /* * Plugin setup diff --git a/src/plugins/data_views/public/plugin.ts b/src/plugins/data_views/public/plugin.ts index 929512d70d926..119d785139c90 100644 --- a/src/plugins/data_views/public/plugin.ts +++ b/src/plugins/data_views/public/plugin.ts @@ -17,7 +17,7 @@ import { } from './types'; import { DataViewsApiClient } from '.'; -import { SavedObjectsClientPublicToCommon } from './saved_objects_client_wrapper'; +import { ContentMagementWrapper } from './content_management_wrapper'; import { UiSettingsPublicToCommon } from './ui_settings_wrapper'; @@ -63,7 +63,7 @@ export class DataViewsPublicPlugin core: CoreStart, { fieldFormats, contentManagement }: DataViewsPublicStartDependencies ): DataViewsPublicPluginStart { - const { uiSettings, http, notifications, application, savedObjects } = core; + const { uiSettings, http, notifications, application } = core; const onNotifDebounced = debounceByKey( notifications.toasts.add.bind(notifications.toasts), @@ -77,10 +77,7 @@ export class DataViewsPublicPlugin return new DataViewsServicePublic({ hasData: this.hasData.start(core), uiSettings: new UiSettingsPublicToCommon(uiSettings), - savedObjectsClient: new SavedObjectsClientPublicToCommon( - contentManagement.client, - savedObjects.client - ), + savedObjectsClient: new ContentMagementWrapper(contentManagement.client), apiClient: new DataViewsApiClient(http), fieldFormats, onNotification: (toastInputFields, key) => { diff --git a/src/plugins/data_views/server/data_views_service_factory.ts b/src/plugins/data_views/server/data_views_service_factory.ts index bc910b3822dba..fb5ae2c5afe3a 100644 --- a/src/plugins/data_views/server/data_views_service_factory.ts +++ b/src/plugins/data_views/server/data_views_service_factory.ts @@ -18,7 +18,7 @@ import { FieldFormatsStart } from '@kbn/field-formats-plugin/server'; import { DataViewsService } from '../common'; import { UiSettingsServerToCommon } from './ui_settings_wrapper'; import { IndexPatternsApiServer } from './index_patterns_api_client'; -import { SavedObjectsClientServerToCommon } from './saved_objects_client_wrapper'; +import { SavedObjectsClientWrapper } from './saved_objects_client_wrapper'; interface DataViewsServiceFactoryDeps { logger: Logger; @@ -44,7 +44,7 @@ export const dataViewsServiceFactory = (deps: DataViewsServiceFactoryDeps) => return new DataViewsService({ uiSettings: new UiSettingsServerToCommon(uiSettingsClient), - savedObjectsClient: new SavedObjectsClientServerToCommon(savedObjectsClient), + savedObjectsClient: new SavedObjectsClientWrapper(savedObjectsClient), apiClient: new IndexPatternsApiServer(elasticsearchClient, savedObjectsClient), fieldFormats: formats, onError: (error) => { diff --git a/src/plugins/data_views/server/index.ts b/src/plugins/data_views/server/index.ts index 40b9030e7d180..553f1a48d1d6d 100644 --- a/src/plugins/data_views/server/index.ts +++ b/src/plugins/data_views/server/index.ts @@ -57,5 +57,5 @@ export { export type { SERVICE_KEY_TYPE } from './constants'; -export type { FieldSpec, SavedObjectsClientCommon } from '../common/types'; +export type { FieldSpec } from '../common/types'; export { DataViewsService, DataView } from '../common/data_views'; diff --git a/src/plugins/data_views/server/saved_objects_client_wrapper.test.ts b/src/plugins/data_views/server/saved_objects_client_wrapper.test.ts index e5dc83f7e109b..9fba85e5e76c8 100644 --- a/src/plugins/data_views/server/saved_objects_client_wrapper.test.ts +++ b/src/plugins/data_views/server/saved_objects_client_wrapper.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SavedObjectsClientServerToCommon } from './saved_objects_client_wrapper'; +import { SavedObjectsClientWrapper } from './saved_objects_client_wrapper'; import { SavedObjectsClientContract } from '@kbn/core/server'; import { DataViewSavedObjectConflictError } from '../common'; @@ -21,7 +21,7 @@ describe('SavedObjectsClientPublicToCommon', () => { soClient.resolve = jest .fn() .mockResolvedValue({ outcome: 'exactMatch', saved_object: mockedSavedObject }); - const service = new SavedObjectsClientServerToCommon(soClient); + const service = new SavedObjectsClientWrapper(soClient); const result = await service.get('1'); expect(result).toStrictEqual(mockedSavedObject); }); @@ -33,7 +33,7 @@ describe('SavedObjectsClientPublicToCommon', () => { soClient.resolve = jest .fn() .mockResolvedValue({ outcome: 'aliasMatch', saved_object: mockedSavedObject }); - const service = new SavedObjectsClientServerToCommon(soClient); + const service = new SavedObjectsClientWrapper(soClient); const result = await service.get('1'); expect(result).toStrictEqual(mockedSavedObject); }); @@ -46,7 +46,7 @@ describe('SavedObjectsClientPublicToCommon', () => { soClient.resolve = jest .fn() .mockResolvedValue({ outcome: 'conflict', saved_object: mockedSavedObject }); - const service = new SavedObjectsClientServerToCommon(soClient); + const service = new SavedObjectsClientWrapper(soClient); await expect(service.get('1')).rejects.toThrow(DataViewSavedObjectConflictError); }); diff --git a/src/plugins/data_views/server/saved_objects_client_wrapper.ts b/src/plugins/data_views/server/saved_objects_client_wrapper.ts index a8902904411df..eb85a60c22a6a 100644 --- a/src/plugins/data_views/server/saved_objects_client_wrapper.ts +++ b/src/plugins/data_views/server/saved_objects_client_wrapper.ts @@ -9,7 +9,7 @@ import { SavedObjectsClientContract, SavedObject } from '@kbn/core/server'; import { DataViewAttributes, - SavedObjectsClientCommon, + PersistenceAPI, SavedObjectsClientCommonFindArgs, } from '../common/types'; import { DataViewSavedObjectConflictError } from '../common/errors'; @@ -17,7 +17,7 @@ import { DataViewSavedObjectConflictError } from '../common/errors'; import type { DataViewCrudTypes } from '../common/content_management'; import { DATA_VIEW_SAVED_OBJECT_TYPE } from '../common'; -export class SavedObjectsClientServerToCommon implements SavedObjectsClientCommon { +export class SavedObjectsClientWrapper implements PersistenceAPI { private savedObjectClient: SavedObjectsClientContract; constructor(savedObjectClient: SavedObjectsClientContract) { this.savedObjectClient = savedObjectClient; diff --git a/src/plugins/saved_search/common/expressions/index.ts b/src/plugins/saved_search/common/expressions/index.ts new file mode 100644 index 0000000000000..1818c4c96299e --- /dev/null +++ b/src/plugins/saved_search/common/expressions/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { kibanaContext } from './kibana_context_type'; diff --git a/src/plugins/data/common/search/expressions/kibana_context.test.ts b/src/plugins/saved_search/common/expressions/kibana_context.test.ts similarity index 87% rename from src/plugins/data/common/search/expressions/kibana_context.test.ts rename to src/plugins/saved_search/common/expressions/kibana_context.test.ts index 211327fa152bb..dfb5ccfbf73eb 100644 --- a/src/plugins/data/common/search/expressions/kibana_context.test.ts +++ b/src/plugins/saved_search/common/expressions/kibana_context.test.ts @@ -9,17 +9,16 @@ import { FilterStateStore, buildFilter, FILTERS } from '@kbn/es-query'; import type { DeeplyMockedKeys } from '@kbn/utility-types-jest'; import type { ExecutionContext } from '@kbn/expressions-plugin/common'; -import { KibanaContext } from './kibana_context_type'; +import { KibanaContext, ExpressionFunctionKibanaContext } from '@kbn/data-plugin/common'; +import { fromSavedSearchAttributes } from '../service/saved_searches_utils'; +import type { SavedSearchAttributes, SavedSearch } from '../types'; -import { - getKibanaContextFn, - ExpressionFunctionKibanaContext, - KibanaContextStartDependencies, -} from './kibana_context'; +import { getKibanaContextFn, KibanaContextStartDependencies } from './kibana_context'; type StartServicesMock = DeeplyMockedKeys; const createExecutionContextMock = (): DeeplyMockedKeys => ({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any abortSignal: {} as any, getExecutionContext: jest.fn(), getSearchContext: jest.fn(), @@ -41,23 +40,26 @@ describe('kibanaContextFn', () => { beforeEach(async () => { kibanaContextFn = getKibanaContextFn(getStartServicesMock); startServicesMock = { - savedObjectsClient: { - create: jest.fn(), - delete: jest.fn(), - find: jest.fn(), - get: jest.fn(), - getSavedSearch: jest.fn(), - update: jest.fn(), - }, + getSavedSearch: jest.fn(), }; }); it('merges and deduplicates queries from different sources', async () => { const { fn } = kibanaContextFn; - startServicesMock.savedObjectsClient.getSavedSearch.mockResolvedValue({ - attributes: { - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ + startServicesMock.getSavedSearch.mockResolvedValue( + fromSavedSearchAttributes( + 'abc', + { + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + query: [], + }), + }, + } as SavedSearchAttributes, + [], + undefined, + { + getFields: () => ({ query: [ { language: 'kuery', @@ -84,10 +86,12 @@ describe('kibanaContextFn', () => { }, }, ], + filter: [], }), - }, - }, - } as any); + } as unknown as SavedSearch['searchSource'], + {} as SavedSearch['sharingSavedObjectProps'] + ) + ); const args = { ...emptyArgs, q: [ diff --git a/src/plugins/saved_search/common/expressions/kibana_context.ts b/src/plugins/saved_search/common/expressions/kibana_context.ts new file mode 100644 index 0000000000000..35e675783ba7f --- /dev/null +++ b/src/plugins/saved_search/common/expressions/kibana_context.ts @@ -0,0 +1,139 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { isEqual, uniqBy } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { ExecutionContext } from '@kbn/expressions-plugin/common'; +import { Filter, fromCombinedFilter } from '@kbn/es-query'; +import { Query, uniqFilters } from '@kbn/es-query'; +import { unboxExpressionValue } from '@kbn/expressions-plugin/common'; +import { SavedObjectReference } from '@kbn/core/server'; +import { ExpressionFunctionKibanaContext } from '@kbn/data-plugin/common'; +import { SavedSearch } from '../types'; + +export interface KibanaContextStartDependencies { + getSavedSearch: (id: string) => Promise; +} + +const mergeQueries = (first: Query | Query[] = [], second: Query | Query[]) => + uniqBy( + [...(Array.isArray(first) ? first : [first]), ...(Array.isArray(second) ? second : [second])], + (n) => JSON.stringify(n.query) + ); + +export const getKibanaContextFn = ( + getStartDependencies: ( + getKibanaRequest: ExecutionContext['getKibanaRequest'] + ) => Promise +) => { + const kibanaContextFunction: ExpressionFunctionKibanaContext = { + name: 'kibana_context', + type: 'kibana_context', + inputTypes: ['kibana_context', 'null'], + help: i18n.translate('savedSearch.kibana_context.help', { + defaultMessage: 'Updates kibana global context', + }), + args: { + q: { + types: ['kibana_query', 'null'], + multi: true, + aliases: ['query', '_'], + help: i18n.translate('savedSearch.kibana_context.q.help', { + defaultMessage: 'Specify Kibana free form text query', + }), + }, + filters: { + types: ['kibana_filter', 'null'], + multi: true, + help: i18n.translate('savedSearch.kibana_context.filters.help', { + defaultMessage: 'Specify Kibana generic filters', + }), + }, + timeRange: { + types: ['timerange', 'null'], + default: null, + help: i18n.translate('savedSearch.kibana_context.timeRange.help', { + defaultMessage: 'Specify Kibana time range filter', + }), + }, + savedSearchId: { + types: ['string', 'null'], + default: null, + help: i18n.translate('savedSearch.kibana_context.savedSearchId.help', { + defaultMessage: 'Specify saved search ID to be used for queries and filters', + }), + }, + }, + + extract(state) { + const references: SavedObjectReference[] = []; + if (state.savedSearchId.length && typeof state.savedSearchId[0] === 'string') { + const refName = 'kibana_context.savedSearchId'; + references.push({ + name: refName, + type: 'search', + id: state.savedSearchId[0] as string, + }); + return { + state: { + ...state, + savedSearchId: [refName], + }, + references, + }; + } + return { state, references }; + }, + + inject(state, references) { + const reference = references.find((r) => r.name === 'kibana_context.savedSearchId'); + if (reference) { + state.savedSearchId[0] = reference.id; + } + return state; + }, + + async fn(input, args, { getKibanaRequest }) { + const { getSavedSearch } = await getStartDependencies(getKibanaRequest); + + const timeRange = args.timeRange || input?.timeRange; + let queries = mergeQueries(input?.query, args?.q?.filter(Boolean) || []); + const filterFromArgs = (args?.filters?.map(unboxExpressionValue) || []) as Filter[]; + + let filters = [...(input?.filters || [])]; + + if (args.savedSearchId) { + const obj = await getSavedSearch(args.savedSearchId); + const { query, filter } = obj.searchSource.getFields(); + + if (query) { + queries = mergeQueries(queries, query as Query); + } + if (filter) { + filters = [...filters, ...(Array.isArray(filter) ? filter : [filter])] as Filter[]; + } + } + const uniqueArgFilters = filterFromArgs.filter( + (argF) => + !filters.some((f) => { + return isEqual(fromCombinedFilter(f).query, argF.query); + }) + ); + + filters = [...filters, ...uniqueArgFilters]; + + return { + type: 'kibana_context', + query: queries, + filters: uniqFilters(filters.filter((f: Filter) => !f.meta?.disabled)), + timeRange, + }; + }, + }; + return kibanaContextFunction; +}; diff --git a/src/plugins/saved_search/common/expressions/kibana_context_type.ts b/src/plugins/saved_search/common/expressions/kibana_context_type.ts new file mode 100644 index 0000000000000..995a438d53526 --- /dev/null +++ b/src/plugins/saved_search/common/expressions/kibana_context_type.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ExpressionValueFilter } from '@kbn/expressions-plugin/common'; +import { adaptToExpressionValueFilter, KibanaContext } from '@kbn/data-plugin/common'; + +export const kibanaContext = { + name: 'kibana_context', + from: { + null: () => { + return { + type: 'kibana_context', + }; + }, + }, + to: { + null: () => { + return { + type: 'null', + }; + }, + filter: (input: KibanaContext): ExpressionValueFilter => { + const { filters = [] } = input; + return { + type: 'filter', + filterType: 'filter', + and: filters.map(adaptToExpressionValueFilter), + }; + }, + }, +}; diff --git a/src/plugins/saved_search/common/index.ts b/src/plugins/saved_search/common/index.ts index 2a888c3067edd..8915ab582b3e2 100644 --- a/src/plugins/saved_search/common/index.ts +++ b/src/plugins/saved_search/common/index.ts @@ -23,3 +23,4 @@ export enum VIEW_MODE { export { SavedSearchType } from './constants'; export { LATEST_VERSION } from './constants'; +export { getKibanaContextFn } from './expressions/kibana_context'; diff --git a/src/plugins/saved_search/public/services/saved_searches/get_saved_searches.test.ts b/src/plugins/saved_search/common/service/get_saved_searches.test.ts similarity index 91% rename from src/plugins/saved_search/public/services/saved_searches/get_saved_searches.test.ts rename to src/plugins/saved_search/common/service/get_saved_searches.test.ts index e2de4581b15db..05893f5c36e64 100644 --- a/src/plugins/saved_search/public/services/saved_searches/get_saved_searches.test.ts +++ b/src/plugins/saved_search/common/service/get_saved_searches.test.ts @@ -6,26 +6,25 @@ * Side Public License, v 1. */ import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import { contentManagementMock } from '@kbn/content-management-plugin/public/mocks'; -import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { getSavedSearch } from './get_saved_searches'; import { SavedObjectsTaggingApi } from '@kbn/saved-objects-tagging-oss-plugin/public'; +import type { GetSavedSearchDependencies } from './get_saved_searches'; describe('getSavedSearch', () => { - let search: DataPublicPluginStart['search']; - let cmClient: ContentManagementPublicStart['client']; + let searchSourceCreate: DataPublicPluginStart['search']['searchSource']['create']; + let getSavedSrch: GetSavedSearchDependencies['getSavedSrch']; beforeEach(() => { - cmClient = contentManagementMock.createStartContract().client; - search = dataPluginMock.createStartContract().search; + getSavedSrch = jest.fn(); + searchSourceCreate = dataPluginMock.createStartContract().search.searchSource.create; }); test('should throw an error if so not found', async () => { let errorMessage = 'No error thrown.'; - cmClient.get = jest.fn().mockReturnValue({ + getSavedSrch = jest.fn().mockReturnValue({ statusCode: 404, error: 'Not Found', message: 'Saved object [ccf1af80-2297-11ec-86e0-1155ffb9c7a7] not found', @@ -33,8 +32,8 @@ describe('getSavedSearch', () => { try { await getSavedSearch('ccf1af80-2297-11ec-86e0-1155ffb9c7a7', { - contentManagement: cmClient, - search, + getSavedSrch, + searchSourceCreate, }); } catch (error) { errorMessage = error.message; @@ -46,7 +45,7 @@ describe('getSavedSearch', () => { }); test('should find saved search', async () => { - cmClient.get = jest.fn().mockReturnValue({ + getSavedSrch = jest.fn().mockReturnValue({ item: { attributes: { kibanaSavedObjectMeta: { @@ -77,11 +76,11 @@ describe('getSavedSearch', () => { }); const savedSearch = await getSavedSearch('ccf1af80-2297-11ec-86e0-1155ffb9c7a7', { - contentManagement: cmClient, - search, + getSavedSrch, + searchSourceCreate, }); - expect(cmClient.get).toHaveBeenCalled(); + expect(getSavedSrch).toHaveBeenCalled(); expect(savedSearch).toMatchInlineSnapshot(` Object { "breakdownField": undefined, @@ -150,7 +149,7 @@ describe('getSavedSearch', () => { }); test('should find saved search with sql mode', async () => { - cmClient.get = jest.fn().mockReturnValue({ + getSavedSrch = jest.fn().mockReturnValue({ item: { attributes: { kibanaSavedObjectMeta: { @@ -182,11 +181,11 @@ describe('getSavedSearch', () => { }); const savedSearch = await getSavedSearch('ccf1af80-2297-11ec-86e0-1155ffb9c7a7', { - contentManagement: cmClient, - search, + getSavedSrch, + searchSourceCreate, }); - expect(cmClient.get).toHaveBeenCalled(); + expect(getSavedSrch).toHaveBeenCalled(); expect(savedSearch).toMatchInlineSnapshot(` Object { "breakdownField": undefined, @@ -255,7 +254,7 @@ describe('getSavedSearch', () => { }); it('should call savedObjectsTagging.ui.getTagIdsFromReferences', async () => { - cmClient.get = jest.fn().mockReturnValue({ + getSavedSrch = jest.fn().mockReturnValue({ item: { attributes: { kibanaSavedObjectMeta: { @@ -296,8 +295,8 @@ describe('getSavedSearch', () => { }, } as unknown as SavedObjectsTaggingApi; await getSavedSearch('ccf1af80-2297-11ec-86e0-1155ffb9c7a7', { - contentManagement: cmClient, - search, + getSavedSrch, + searchSourceCreate, savedObjectsTagging, }); expect(savedObjectsTagging.ui.getTagIdsFromReferences).toHaveBeenCalledWith([ diff --git a/src/plugins/saved_search/public/services/saved_searches/get_saved_searches.ts b/src/plugins/saved_search/common/service/get_saved_searches.ts similarity index 65% rename from src/plugins/saved_search/public/services/saved_searches/get_saved_searches.ts rename to src/plugins/saved_search/common/service/get_saved_searches.ts index a6129d05d07bb..63a41a52b5391 100644 --- a/src/plugins/saved_search/public/services/saved_searches/get_saved_searches.ts +++ b/src/plugins/saved_search/common/service/get_saved_searches.ts @@ -6,20 +6,21 @@ * Side Public License, v 1. */ -import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import { injectSearchSourceReferences, parseSearchSourceJSON } from '@kbn/data-plugin/public'; +import type { ISearchStartSearchSource } from '@kbn/data-plugin/common'; +import { injectReferences, parseSearchSourceJSON } from '@kbn/data-plugin/common'; +// these won't exist in on server import type { SpacesApi } from '@kbn/spaces-plugin/public'; import type { SavedObjectsTaggingApi } from '@kbn/saved-objects-tagging-oss-plugin/public'; + import { i18n } from '@kbn/i18n'; -import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; -import type { SavedSearch } from './types'; -import { SAVED_SEARCH_TYPE } from './constants'; +import type { SavedSearch } from '../types'; +import { SavedSearchType as SAVED_SEARCH_TYPE } from '..'; import { fromSavedSearchAttributes } from './saved_searches_utils'; -import type { SavedSearchCrudTypes } from '../../../common/content_management'; +import type { SavedSearchCrudTypes } from '../content_management'; -interface GetSavedSearchDependencies { - search: DataPublicPluginStart['search']; - contentManagement: ContentManagementPublicStart['client']; +export interface GetSavedSearchDependencies { + searchSourceCreate: ISearchStartSearchSource['create']; + getSavedSrch: (id: string) => Promise; spaces?: SpacesApi; savedObjectsTagging?: SavedObjectsTaggingApi; } @@ -32,15 +33,9 @@ const getSavedSearchUrlConflictMessage = async (json: string) => export const getSavedSearch = async ( savedSearchId: string, - { search, spaces, savedObjectsTagging, contentManagement }: GetSavedSearchDependencies + { searchSourceCreate, spaces, savedObjectsTagging, getSavedSrch }: GetSavedSearchDependencies ) => { - const so = await contentManagement.get< - SavedSearchCrudTypes['GetIn'], - SavedSearchCrudTypes['GetOut'] - >({ - contentTypeId: SAVED_SEARCH_TYPE, - id: savedSearchId, - }); + const so = await getSavedSrch(savedSearchId); // @ts-expect-error if (so.error) { @@ -53,6 +48,7 @@ export const getSavedSearch = async ( JSON.stringify({ targetType: SAVED_SEARCH_TYPE, sourceId: savedSearchId, + // front end only targetSpace: (await spaces?.getActiveSpace())?.id, }) ) @@ -65,11 +61,12 @@ export const getSavedSearch = async ( savedSearch.attributes.kibanaSavedObjectMeta?.searchSourceJSON ?? '{}' ); - const searchSourceValues = injectSearchSourceReferences( - parsedSearchSourceJSON as Parameters[0], + const searchSourceValues = injectReferences( + parsedSearchSourceJSON as Parameters[0], savedSearch.references ); + // front end only const tags = savedObjectsTagging ? savedObjectsTagging.ui.getTagIdsFromReferences(savedSearch.references) : undefined; @@ -79,7 +76,7 @@ export const getSavedSearch = async ( savedSearch.attributes, tags, savedSearch.references, - await search.searchSource.create(searchSourceValues), + await searchSourceCreate(searchSourceValues), so.meta ); @@ -92,9 +89,9 @@ export const getSavedSearch = async ( * @param search */ export const getNewSavedSearch = ({ - search, + searchSource, }: { - search: DataPublicPluginStart['search']; + searchSource: ISearchStartSearchSource; }): SavedSearch => ({ - searchSource: search.searchSource.createEmpty(), + searchSource: searchSource.createEmpty(), }); diff --git a/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.test.ts b/src/plugins/saved_search/common/service/saved_searches_utils.test.ts similarity index 97% rename from src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.test.ts rename to src/plugins/saved_search/common/service/saved_searches_utils.test.ts index 4ebf62dffb443..8286276bb898e 100644 --- a/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.test.ts +++ b/src/plugins/saved_search/common/service/saved_searches_utils.test.ts @@ -10,8 +10,7 @@ import { fromSavedSearchAttributes, toSavedSearchAttributes } from './saved_sear import { createSearchSourceMock } from '@kbn/data-plugin/public/mocks'; -import type { SavedSearchAttributes } from '../../../common'; -import type { SavedSearch } from './types'; +import type { SavedSearch, SavedSearchAttributes } from '../types'; describe('saved_searches_utils', () => { describe('fromSavedSearchAttributes', () => { diff --git a/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.ts b/src/plugins/saved_search/common/service/saved_searches_utils.ts similarity index 92% rename from src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.ts rename to src/plugins/saved_search/common/service/saved_searches_utils.ts index 129e1e5ff6dc6..c4e663e5f6352 100644 --- a/src/plugins/saved_search/public/services/saved_searches/saved_searches_utils.ts +++ b/src/plugins/saved_search/common/service/saved_searches_utils.ts @@ -8,11 +8,10 @@ import { pick } from 'lodash'; import type { SavedObjectReference } from '@kbn/core-saved-objects-server'; -import type { SavedSearchAttributes } from '../../../common'; -import { fromSavedSearchAttributes as fromSavedSearchAttributesCommon } from '../../../common'; -import type { SavedSearch } from './types'; +import type { SavedSearchAttributes, SavedSearch } from '..'; +import { fromSavedSearchAttributes as fromSavedSearchAttributesCommon } from '..'; -export { getSavedSearchUrl, getSavedSearchFullPathUrl } from '../../../common'; +export { getSavedSearchUrl, getSavedSearchFullPathUrl } from '..'; export const fromSavedSearchAttributes = ( id: string, diff --git a/src/plugins/saved_search/common/types.ts b/src/plugins/saved_search/common/types.ts index 51c016b7dfbda..3da4276aeb1dd 100644 --- a/src/plugins/saved_search/common/types.ts +++ b/src/plugins/saved_search/common/types.ts @@ -8,6 +8,7 @@ import type { ISearchSource, RefreshInterval, TimeRange } from '@kbn/data-plugin/common'; import type { SavedObjectReference } from '@kbn/core-saved-objects-server'; +import type { SavedObjectsResolveResponse } from '@kbn/core/server'; import { VIEW_MODE } from '.'; export interface DiscoverGridSettings { @@ -75,4 +76,10 @@ export interface SavedSearch { rowsPerPage?: number; breakdownField?: string; references?: SavedObjectReference[]; + sharingSavedObjectProps?: { + outcome?: SavedObjectsResolveResponse['outcome']; + aliasTargetId?: SavedObjectsResolveResponse['alias_target_id']; + aliasPurpose?: SavedObjectsResolveResponse['alias_purpose']; + errorJSON?: string; + }; } diff --git a/src/plugins/saved_search/kibana.jsonc b/src/plugins/saved_search/kibana.jsonc index 908a397bd590d..03df75a7d7924 100644 --- a/src/plugins/saved_search/kibana.jsonc +++ b/src/plugins/saved_search/kibana.jsonc @@ -9,7 +9,8 @@ "browser": true, "requiredPlugins": [ "data", - "contentManagement" + "contentManagement", + "expressions" ], "optionalPlugins": [ "spaces", diff --git a/src/plugins/data/public/search/expressions/kibana_context.ts b/src/plugins/saved_search/public/expressions/kibana_context.ts similarity index 71% rename from src/plugins/data/public/search/expressions/kibana_context.ts rename to src/plugins/saved_search/public/expressions/kibana_context.ts index cfbac7ad8a5ca..89078aa424bde 100644 --- a/src/plugins/data/public/search/expressions/kibana_context.ts +++ b/src/plugins/saved_search/public/expressions/kibana_context.ts @@ -7,9 +7,8 @@ */ import { StartServicesAccessor } from '@kbn/core/public'; -import { SavedObjectsClientCommon } from '@kbn/data-views-plugin/public'; -import { getKibanaContextFn } from '../../../common/search/expressions'; -import { DataPublicPluginStart, DataStartDependencies } from '../../types'; +import { getKibanaContextFn } from '../../common'; +import { SavedSearchPublicPluginStart, SavedSearchPublicStartDependencies } from '../plugin'; /** * This is some glue code that takes in `core.getStartServices`, extracts the dependencies @@ -25,15 +24,17 @@ import { DataPublicPluginStart, DataStartDependencies } from '../../types'; * * @internal */ + export function getKibanaContext({ getStartServices, }: { - getStartServices: StartServicesAccessor; + getStartServices: StartServicesAccessor< + SavedSearchPublicStartDependencies, + SavedSearchPublicPluginStart + >; }) { return getKibanaContextFn(async () => { - const [core] = await getStartServices(); - return { - savedObjectsClient: core.savedObjects.client as unknown as SavedObjectsClientCommon, - }; + const [, , { get: getSavedSearch }] = await getStartServices(); + return { getSavedSearch }; }); } diff --git a/src/plugins/saved_search/public/plugin.ts b/src/plugins/saved_search/public/plugin.ts index 80fe6b6fbc0e7..2d8d53c821ae5 100644 --- a/src/plugins/saved_search/public/plugin.ts +++ b/src/plugins/saved_search/public/plugin.ts @@ -6,10 +6,11 @@ * Side Public License, v 1. */ -import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; +import { CoreSetup, CoreStart, Plugin, StartServicesAccessor } from '@kbn/core/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { SpacesApi } from '@kbn/spaces-plugin/public'; import type { SavedObjectTaggingOssPluginStart } from '@kbn/saved-objects-tagging-oss-plugin/public'; +import { ExpressionsSetup } from '@kbn/expressions-plugin/public'; import { i18n } from '@kbn/i18n'; import type { ContentManagementPublicSetup, @@ -25,6 +26,8 @@ import { import { SavedSearch, SavedSearchAttributes } from '../common/types'; import { SavedSearchType, LATEST_VERSION } from '../common'; import { SavedSearchesService } from './services/saved_searches/saved_searches_service'; +import { kibanaContext } from '../common/expressions'; +import { getKibanaContext } from './expressions/kibana_context'; /** * Saved search plugin public Setup contract @@ -50,6 +53,7 @@ export interface SavedSearchPublicPluginStart { */ export interface SavedSearchPublicSetupDependencies { contentManagement: ContentManagementPublicSetup; + expressions: ExpressionsSetup; } /** @@ -71,7 +75,10 @@ export class SavedSearchPublicPlugin SavedSearchPublicStartDependencies > { - public setup(core: CoreSetup, { contentManagement }: SavedSearchPublicSetupDependencies) { + public setup( + { getStartServices }: CoreSetup, + { contentManagement, expressions }: SavedSearchPublicSetupDependencies + ) { contentManagement.registry.register({ id: SavedSearchType, version: { @@ -82,6 +89,17 @@ export class SavedSearchPublicPlugin }), }); + expressions.registerFunction( + getKibanaContext({ getStartServices } as { + getStartServices: StartServicesAccessor< + SavedSearchPublicStartDependencies, + SavedSearchPublicPluginStart + >; + }) + ); + + expressions.registerType(kibanaContext); + return {}; } diff --git a/src/plugins/saved_search/public/services/saved_searches/index.ts b/src/plugins/saved_search/public/services/saved_searches/index.ts index e09ce932345b3..456e777292778 100644 --- a/src/plugins/saved_search/public/services/saved_searches/index.ts +++ b/src/plugins/saved_search/public/services/saved_searches/index.ts @@ -6,8 +6,11 @@ * Side Public License, v 1. */ -export { getSavedSearch, getNewSavedSearch } from './get_saved_searches'; -export { getSavedSearchUrl, getSavedSearchFullPathUrl } from './saved_searches_utils'; +export { getSavedSearch, getNewSavedSearch } from '../../../common/service/get_saved_searches'; +export { + getSavedSearchUrl, + getSavedSearchFullPathUrl, +} from '../../../common/service/saved_searches_utils'; export type { SaveSavedSearchOptions } from './save_saved_searches'; export { saveSavedSearch } from './save_saved_searches'; export { SAVED_SEARCH_TYPE } from './constants'; diff --git a/src/plugins/saved_search/public/services/saved_searches/save_saved_searches.ts b/src/plugins/saved_search/public/services/saved_searches/save_saved_searches.ts index 9ea35b8389f00..4792680285bfc 100644 --- a/src/plugins/saved_search/public/services/saved_searches/save_saved_searches.ts +++ b/src/plugins/saved_search/public/services/saved_searches/save_saved_searches.ts @@ -10,7 +10,7 @@ import type { SavedObjectsTaggingApi } from '@kbn/saved-objects-tagging-oss-plug import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; import type { SavedSearch } from './types'; import { SAVED_SEARCH_TYPE } from './constants'; -import { toSavedSearchAttributes } from './saved_searches_utils'; +import { toSavedSearchAttributes } from '../../../common/service/saved_searches_utils'; import type { SavedSearchCrudTypes } from '../../../common/content_management'; export interface SaveSavedSearchOptions { diff --git a/src/plugins/saved_search/public/services/saved_searches/saved_searches_service.ts b/src/plugins/saved_search/public/services/saved_searches/saved_searches_service.ts index 35a7ea5c571af..4b38626e63b21 100644 --- a/src/plugins/saved_search/public/services/saved_searches/saved_searches_service.ts +++ b/src/plugins/saved_search/public/services/saved_searches/saved_searches_service.ts @@ -27,10 +27,16 @@ export class SavedSearchesService { get = (savedSearchId: string) => { const { search, contentManagement, spaces, savedObjectsTaggingOss } = this.deps; + const getViaCm = (id: string) => + contentManagement.get({ + contentTypeId: SavedSearchType, + id, + }); + return getSavedSearch(savedSearchId, { - search, - contentManagement, + getSavedSrch: getViaCm, spaces, + searchSourceCreate: search.searchSource.create, savedObjectsTagging: savedObjectsTaggingOss?.getTaggingApi(), }); }; @@ -45,7 +51,7 @@ export class SavedSearchesService { }); return result.hits; }; - getNew = () => getNewSavedSearch({ search: this.deps.search }); + getNew = () => getNewSavedSearch({ searchSource: this.deps.search.searchSource }); find = async (search: string) => { const { contentManagement } = this.deps; diff --git a/src/plugins/data/server/search/expressions/kibana_context.ts b/src/plugins/saved_search/server/expressions/kibana_context.ts similarity index 53% rename from src/plugins/data/server/search/expressions/kibana_context.ts rename to src/plugins/saved_search/server/expressions/kibana_context.ts index 14fdcdd784f33..2c75dca8a2956 100644 --- a/src/plugins/data/server/search/expressions/kibana_context.ts +++ b/src/plugins/saved_search/server/expressions/kibana_context.ts @@ -7,9 +7,10 @@ */ import { StartServicesAccessor } from '@kbn/core/server'; -import { SavedObjectsClientCommon } from '@kbn/data-views-plugin/server'; -import { getKibanaContextFn } from '../../../common/search/expressions'; -import { DataPluginStart, DataPluginStartDependencies } from '../../plugin'; +import { getKibanaContextFn } from '../../common'; +import { SavedSearchServerStartDeps } from '../plugin'; +import { getSavedSearch } from '../../common/service/get_saved_searches'; +import { SavedSearchAttributes } from '../../common/types'; /** * This is some glue code that takes in `core.getStartServices`, extracts the dependencies @@ -25,20 +26,36 @@ import { DataPluginStart, DataPluginStartDependencies } from '../../plugin'; * * @internal */ -export function getKibanaContext({ - getStartServices, -}: { - getStartServices: StartServicesAccessor; -}) { +export function getKibanaContext( + getStartServices: StartServicesAccessor +) { return getKibanaContextFn(async (getKibanaRequest) => { const request = getKibanaRequest && getKibanaRequest(); if (!request) { throw new Error('KIBANA_CONTEXT_KIBANA_REQUEST_MISSING'); } - const [{ savedObjects }] = await getStartServices(); + const [{ savedObjects }, { data }] = await getStartServices(); return { - savedObjectsClient: savedObjects.getScopedClient(request) as any as SavedObjectsClientCommon, + getSavedSearch: async (id: string) => { + const searchSourceCreate = (await data.search.searchSource.asScoped(request)).create; + const getSavedSrch = async (searchId: string) => { + const so = await savedObjects + .getScopedClient(request) + .resolve('search', searchId); + + return { + item: so.saved_object, + meta: { + outcome: so.outcome, + aliasTargetId: so.alias_target_id, + aliasPurpose: so.alias_purpose, + }, + }; + }; + + return getSavedSearch(id, { searchSourceCreate, getSavedSrch }); + }, }; }); } diff --git a/src/plugins/saved_search/server/plugin.ts b/src/plugins/saved_search/server/plugin.ts index adb6492eae42e..0f3e41894ff22 100644 --- a/src/plugins/saved_search/server/plugin.ts +++ b/src/plugins/saved_search/server/plugin.ts @@ -7,21 +7,41 @@ */ import { CoreSetup, CoreStart, Plugin } from '@kbn/core/server'; -import type { PluginSetup as DataPluginSetup } from '@kbn/data-plugin/server'; +import { StartServicesAccessor } from '@kbn/core/server'; +import type { + PluginSetup as DataPluginSetup, + PluginStart as DataPluginStart, +} from '@kbn/data-plugin/server'; import type { ContentManagementServerSetup } from '@kbn/content-management-plugin/server'; +import { ExpressionsServerSetup } from '@kbn/expressions-plugin/server'; import { getSavedSearchObjectType } from './saved_objects'; import { SavedSearchType, LATEST_VERSION } from '../common'; import { SavedSearchStorage } from './content_management'; +import { kibanaContext } from '../common/expressions'; +import { getKibanaContext } from './expressions/kibana_context'; +import { getSavedSearch } from '../common/service/get_saved_searches'; -export class SavedSearchServerPlugin implements Plugin { +/** + * Saved search plugin server Setup contract + */ +export interface SavedSearchPublicSetupDependencies { + data: DataPluginSetup; + contentManagement: ContentManagementServerSetup; + expressions: ExpressionsServerSetup; +} + +export interface SavedSearchServerStartDeps { + data: DataPluginStart; +} + +export class SavedSearchServerPlugin + implements Plugin +{ public setup( core: CoreSetup, - plugins: { - data: DataPluginSetup; - contentManagement: ContentManagementServerSetup; - } + { data, contentManagement, expressions }: SavedSearchPublicSetupDependencies ) { - plugins.contentManagement.register({ + contentManagement.register({ id: SavedSearchType, storage: new SavedSearchStorage(), version: { @@ -29,16 +49,23 @@ export class SavedSearchServerPlugin implements Plugin { }, }); - const getSearchSourceMigrations = plugins.data.search.searchSource.getAllMigrations.bind( - plugins.data.search.searchSource - ); + const searchSource = data.search.searchSource; + + const getSearchSourceMigrations = searchSource.getAllMigrations.bind(searchSource); core.savedObjects.registerType(getSavedSearchObjectType(getSearchSourceMigrations)); + expressions.registerType(kibanaContext); + expressions.registerFunction( + getKibanaContext(core.getStartServices as StartServicesAccessor) + ); + return {}; } public start(core: CoreStart) { - return {}; + return { + getSavedSearch, + }; } public stop() {} diff --git a/src/plugins/saved_search/tsconfig.json b/src/plugins/saved_search/tsconfig.json index b1c9253b1fd25..468279bbf31cc 100644 --- a/src/plugins/saved_search/tsconfig.json +++ b/src/plugins/saved_search/tsconfig.json @@ -22,6 +22,9 @@ "@kbn/object-versioning", "@kbn/content-management-utils", "@kbn/content-management-plugin", + "@kbn/es-query", + "@kbn/utility-types-jest", + "@kbn/expressions-plugin", ], "exclude": [ "target/**/*", diff --git a/test/functional/fixtures/kbn_archiver/saved_search.json b/test/functional/fixtures/kbn_archiver/saved_search.json new file mode 100644 index 0000000000000..dced24b053ff3 --- /dev/null +++ b/test/functional/fixtures/kbn_archiver/saved_search.json @@ -0,0 +1,27 @@ +{ + "attributes": { + "columns": [ + "_source" + ], + "description": "A Saved Search Description", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"geo.src :\\\"FR\\\" \",\"language\":\"kuery\"},\"filter\":[]}" + }, + "sort": [], + "title": "A Saved Search", + "version": 1, + "timeRange" : { + "from": "2006-09-21T00:00:00Z", + "to": "2015-09-22T00:00:00Z" + } + }, + "coreMigrationVersion": "7.17.1", + "id": "ab12e3c0-f231-11e6-9486-733b1ac9221a", + "migrationVersion": { + "search": "7.9.3" + }, + "references": [], + "type": "search", + "version": "WzQzLDJd" +} diff --git a/test/interpreter_functional/test_suites/run_pipeline/esaggs.ts b/test/interpreter_functional/test_suites/run_pipeline/esaggs.ts index f71fa58cd7cc5..d29c63b467b64 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/esaggs.ts +++ b/test/interpreter_functional/test_suites/run_pipeline/esaggs.ts @@ -23,6 +23,7 @@ export default function ({ updateBaselines, }: FtrProviderContext & { updateBaselines: boolean }) { const supertest = getService('supertest'); + const kibanaServer = getService('kibanaServer'); let expectExpression: ExpectExpression; const expectClientToMatchServer = async (title: string, expression: string) => { @@ -92,6 +93,43 @@ export default function ({ }); }); + describe('loads a saved search', () => { + before(async () => { + await kibanaServer.importExport.load( + 'test/functional/fixtures/kbn_archiver/saved_search.json' + ); + }); + after(async () => { + await kibanaServer.importExport.unload( + 'test/functional/fixtures/kbn_archiver/saved_search.json' + ); + }); + + const expression = ` + kibana_context savedSearchId="ab12e3c0-f231-11e6-9486-733b1ac9221a" + | esaggs index={indexPatternLoad id='logstash-*'} + aggs={aggCount id="1" enabled=true schema="metric"} + `; + + it('correctly applies filter from saved search', async () => { + const result = await expectExpression('esaggs_saved_searches', expression).getResponse(); + expect(getCell(result, 0, 0)).to.be(119); + }); + + it('correctly applies filter - on the server', async () => { + await supertest + .post('/api/interpreter_functional/run_expression') + .set('kbn-xsrf', 'anything') + .send({ expression, input: undefined }) + .expect(200) + .expect(({ body }) => { + expect(body.columns[0].meta.index).to.be('logstash-*'); + expect(body.columns[0].meta.source).to.be('esaggs'); + expect(getCell(body, 0, 0)).to.be(119); + }); + }); + }); + describe('correctly runs on the server', () => { it('runs the provided agg on the server', async () => { const expression = ` diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts b/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts index f932af1143f82..bdec35bfa6054 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts @@ -8,7 +8,7 @@ import type { IUiSettingsClient } from '@kbn/core/public'; import { DataView } from '@kbn/data-views-plugin/common'; import { createSearchItems } from './new_job_utils'; -import { fromSavedSearchAttributes } from '@kbn/saved-search-plugin/public/services/saved_searches/saved_searches_utils'; +import { fromSavedSearchAttributes } from '@kbn/saved-search-plugin/common'; import type { ISearchSource } from '@kbn/data-plugin/public'; describe('createSearchItems', () => { @@ -42,17 +42,9 @@ describe('createSearchItems', () => { isTextBasedQuery: false, }, [], - [ - { - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', - type: 'index-pattern', - id: '7e252840-bd27-11ea-8a6c-75d1a0bd08ab', - }, - ], { getField: getFieldMock(searchSource), - } as unknown as ISearchSource, - {} + } as unknown as ISearchSource ); test('should match data view', () => { diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 8527f1d41c74a..ba8376cf9ca10 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -2004,11 +2004,11 @@ "data.search.functions.ipRange.from.help": "Spécifier l'adresse de début", "data.search.functions.ipRange.help": "Créer une plage d'IP", "data.search.functions.ipRange.to.help": "Spécifier l'adresse de fin", - "data.search.functions.kibana_context.filters.help": "Spécifier des filtres génériques Kibana", - "data.search.functions.kibana_context.help": "Met à jour le contexte général de Kibana.", - "data.search.functions.kibana_context.q.help": "Spécifier une recherche en texte libre Kibana", - "data.search.functions.kibana_context.savedSearchId.help": "Spécifier l'ID de recherche enregistrée à utiliser pour les requêtes et les filtres", - "data.search.functions.kibana_context.timeRange.help": "Spécifier le filtre de plage temporelle Kibana", + "savedSearch.kibana_context.filters.help": "Spécifier des filtres génériques Kibana", + "savedSearch.kibana_context.help": "Met à jour le contexte général de Kibana.", + "savedSearch.kibana_context.q.help": "Spécifier une recherche en texte libre Kibana", + "savedSearch.kibana_context.savedSearchId.help": "Spécifier l'ID de recherche enregistrée à utiliser pour les requêtes et les filtres", + "savedSearch.kibana_context.timeRange.help": "Spécifier le filtre de plage temporelle Kibana", "data.search.functions.kibana.help": "Permet d’obtenir le contexte général de Kibana.", "data.search.functions.kibanaFilter.disabled.help": "Si le filtre doit être désactivé", "data.search.functions.kibanaFilter.field.help": "Spécifier une recherche en texte libre esdsl", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 2f48fe500ec54..9d30c9d27076c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2004,11 +2004,11 @@ "data.search.functions.ipRange.from.help": "開始アドレスを指定", "data.search.functions.ipRange.help": "IP範囲を作成", "data.search.functions.ipRange.to.help": "終了アドレスを指定", - "data.search.functions.kibana_context.filters.help": "Kibana ジェネリックフィルターを指定します", - "data.search.functions.kibana_context.help": "Kibana グローバルコンテキストを更新します", - "data.search.functions.kibana_context.q.help": "自由形式の Kibana テキストクエリを指定します", - "data.search.functions.kibana_context.savedSearchId.help": "クエリとフィルターに使用する保存検索ID を指定します。", - "data.search.functions.kibana_context.timeRange.help": "Kibana 時間範囲フィルターを指定します", + "savedSearch.kibana_context.filters.help": "Kibana ジェネリックフィルターを指定します", + "savedSearch.kibana_context.help": "Kibana グローバルコンテキストを更新します", + "savedSearch.kibana_context.q.help": "自由形式の Kibana テキストクエリを指定します", + "savedSearch.kibana_context.savedSearchId.help": "クエリとフィルターに使用する保存検索ID を指定します。", + "savedSearch.kibana_context.timeRange.help": "Kibana 時間範囲フィルターを指定します", "data.search.functions.kibana.help": "Kibana グローバルコンテキストを取得します", "data.search.functions.kibanaFilter.disabled.help": "フィルターは無効でなければなりません", "data.search.functions.kibanaFilter.field.help": "フリーフォームesdslクエリを指定", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e43b03a679480..e317ffc9db76a 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2004,11 +2004,11 @@ "data.search.functions.ipRange.from.help": "指定开始地址", "data.search.functions.ipRange.help": "创建 IP 范围", "data.search.functions.ipRange.to.help": "指定结束地址", - "data.search.functions.kibana_context.filters.help": "指定 Kibana 常规筛选", - "data.search.functions.kibana_context.help": "更新 kibana 全局上下文", - "data.search.functions.kibana_context.q.help": "指定 Kibana 自由格式文本查询", - "data.search.functions.kibana_context.savedSearchId.help": "指定要用于查询和筛选的已保存搜索 ID", - "data.search.functions.kibana_context.timeRange.help": "指定 Kibana 时间范围筛选", + "savedSearch.kibana_context.filters.help": "指定 Kibana 常规筛选", + "savedSearch.kibana_context.help": "更新 kibana 全局上下文", + "savedSearch.kibana_context.q.help": "指定 Kibana 自由格式文本查询", + "savedSearch.kibana_context.savedSearchId.help": "指定要用于查询和筛选的已保存搜索 ID", + "savedSearch.kibana_context.timeRange.help": "指定 Kibana 时间范围筛选", "data.search.functions.kibana.help": "获取 kibana 全局上下文", "data.search.functions.kibanaFilter.disabled.help": "如果禁用该筛选", "data.search.functions.kibanaFilter.field.help": "指定自由格式 esdsl 查询", From f6f5986376fd01a1643fcc15ba71df821eb75890 Mon Sep 17 00:00:00 2001 From: Ashokaditya <1849116+ashokaditya@users.noreply.github.com> Date: Tue, 11 Jul 2023 15:41:35 +0200 Subject: [PATCH 16/97] [Security Solution][Endpoint] Unskip mocked response actions history cypress test (#161533) ## Summary Unskip test that was timing out at indexing test hosts. The timeout has since been increased in elastic/kibana/pull/159518 It was added in elastic/kibana/pull/157777 and skipped in elastic/kibana/pull/156933 thus should be backported to `8.8.1` and `8.9.0` --- .../cypress/e2e/mocked_data/reponse_actions_history.cy.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts index 741164cc6d433..cb6c7c3a96eee 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/reponse_actions_history.cy.ts @@ -32,8 +32,7 @@ describe('Response actions history page', () => { } }); - // Flakey, example build failure: https://buildkite.com/elastic/kibana-pull-request/builds/132245 - it.skip('retains expanded action details on page reload', () => { + it('retains expanded action details on page reload', () => { loadPage(`/app/security/administration/response_actions_history`); cy.getByTestSubj('response-actions-list-expand-button').eq(3).click(); // 4th row on 1st page cy.getByTestSubj('response-actions-list-details-tray').should('exist'); From 7e7293a520f3e96440ff3d9f1b3ba438d0731066 Mon Sep 17 00:00:00 2001 From: Marta Bondyra <4283304+mbondyra@users.noreply.github.com> Date: Tue, 11 Jul 2023 15:51:58 +0200 Subject: [PATCH 17/97] [Lens] Fix a11y issues & small styling issues (#161073) ## Summary Fixes the following issues: 1. Suggestions are not reachable by keyboard navigation (it was actually broken when fixing the [accesibility axe warning](https://github.com/elastic/kibana/issues/154787), I ran it now and it doesn't show now) https://github.com/elastic/kibana/assets/4283304/46c9eb70-4df7-462b-a878-b7d190aaf8c9 2. Dimension removal button is not reachable by keyboard navigation before: https://github.com/elastic/kibana/assets/4283304/5011679b-b05a-48ca-a877-bbc940607b56 after: https://github.com/elastic/kibana/assets/4283304/9d056512-a622-4c1c-aa5b-242e2762e9ae 3. The padding for the reordering groups got a distance between the empty dimension button (btw I have more little fixes for drag and drop look but want to submit it in a separate PR to not ping here Discover team): Screenshot 2023-07-03 at 17 42 41 Screenshot 2023-07-03 at 17 39 11 4. The focus outline for dataview selector and layer chart selector got a nicer rectangular shape before: Screenshot 2023-07-03 at 10 50 52 Screenshot 2023-07-03 at 17 41 18 after: Screenshot 2023-07-03 at 11 11 01 Screenshot 2023-07-03 at 17 39 51 5. The focus outline was corrected for dimension buttons. I also refactored code here to make margins, paddings and gaps the property of the containers and not the items themselves. I think this way it's more correct. before: Screenshot 2023-07-03 at 17 40 54 after: https://github.com/elastic/kibana/assets/4283304/712e2ac8-f81d-4896-b384-164fc2854766 --- .../dimension_buttons/dimension_button.tsx | 29 +++++++++---------- .../dimension_button_icon.tsx | 23 ++++----------- .../dimension_buttons/empty_button.tsx | 7 ++--- .../components/dimension_buttons/trigger.tsx | 1 - .../config_panel/layer_panel.scss | 4 +-- .../editor_frame/config_panel/layer_panel.tsx | 1 + .../editor_frame/suggestion_panel.test.tsx | 2 +- .../editor_frame/suggestion_panel.tsx | 2 +- .../dataview_picker/trigger.tsx | 2 +- .../xy/xy_config_panel/layer_header.tsx | 1 + 10 files changed, 29 insertions(+), 43 deletions(-) diff --git a/src/plugins/visualization_ui_components/public/components/dimension_buttons/dimension_button.tsx b/src/plugins/visualization_ui_components/public/components/dimension_buttons/dimension_button.tsx index 44b158f43cf40..1a72a9b612299 100644 --- a/src/plugins/visualization_ui_components/public/components/dimension_buttons/dimension_button.tsx +++ b/src/plugins/visualization_ui_components/public/components/dimension_buttons/dimension_button.tsx @@ -58,20 +58,14 @@ export function DimensionButton({ css={css` ${useEuiFontSize('s')} border-radius: ${euiThemeVars.euiBorderRadius}; + position: relative; + line-height: 1; + overflow: hidden; display: flex; align-items: center; - overflow: hidden; + gap: ${euiThemeVars.euiSizeS}; min-height: ${euiThemeVars.euiSizeXL}; - position: relative; - - &:hover, - &:focus { - .lnsLayerPanel__dimensionRemove { - visibility: visible; - opacity: 1; - transition: opacity ${euiThemeVars.euiAnimSpeedFast} ease-in-out; - } - } + padding: ${euiThemeVars.euiSizeXS} ${euiThemeVars.euiSizeS}; `} > @@ -120,12 +114,17 @@ export function DimensionButton({ })} onClick={() => onRemoveClick(accessorConfig.columnId)} css={css` - margin-right: ${euiThemeVars.euiSizeS}; - visibility: hidden; - opacity: 0; color: ${euiThemeVars.euiTextSubduedColor}; + transition: ${euiThemeVars.euiAnimSpeedFast} ease-in-out; + transition-property: color, opacity, background-color, transform; + opacity: 0; - &:hover { + .domDragDrop:hover &, + .domDragDrop:focus-within & { + opacity: 1; + } + &:hover, + &:focus { color: ${euiThemeVars.euiColorDangerText}; } `} diff --git a/src/plugins/visualization_ui_components/public/components/dimension_buttons/dimension_button_icon.tsx b/src/plugins/visualization_ui_components/public/components/dimension_buttons/dimension_button_icon.tsx index 6294c27254a56..52e0aa665f54a 100644 --- a/src/plugins/visualization_ui_components/public/components/dimension_buttons/dimension_button_icon.tsx +++ b/src/plugins/visualization_ui_components/public/components/dimension_buttons/dimension_button_icon.tsx @@ -9,21 +9,12 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { css } from '@emotion/react'; -import { euiThemeVars } from '@kbn/ui-theme'; import type { AccessorConfig, Message } from './types'; -const baseIconProps = { - css: css` - margin-left: ${euiThemeVars.euiSizeS}; - `, -} as const; - const getIconFromAccessorConfig = (accessorConfig: AccessorConfig) => ( <> {accessorConfig.triggerIconType === 'color' && accessorConfig.color && ( ( )} {accessorConfig.triggerIconType === 'disabled' && ( ( )} {accessorConfig.triggerIconType === 'invisible' && ( ( )} {accessorConfig.triggerIconType === 'aggregate' && ( ( )} {accessorConfig.triggerIconType === 'colorBy' && ( ( )} {accessorConfig.triggerIconType === 'custom' && accessorConfig.customIcon && ( {accessorConfig.triggerIconType !== 'none' && ( @@ -124,7 +113,7 @@ export function DimensionButtonIcon({ )} {severity && ( - + )} @@ -132,7 +121,7 @@ export function DimensionButtonIcon({ } return ( - + {indicatorIcon} {children} diff --git a/src/plugins/visualization_ui_components/public/components/dimension_buttons/empty_button.tsx b/src/plugins/visualization_ui_components/public/components/dimension_buttons/empty_button.tsx index 5b0cf67789879..9cb2586f3030d 100644 --- a/src/plugins/visualization_ui_components/public/components/dimension_buttons/empty_button.tsx +++ b/src/plugins/visualization_ui_components/public/components/dimension_buttons/empty_button.tsx @@ -33,6 +33,7 @@ export const EmptyDimensionButton = ({ width: 100%; border-radius: ${euiThemeVars.euiBorderRadius} !important; border: ${euiThemeVars.euiBorderWidthThin} dashed ${euiThemeVars.euiBorderColor} !important; + padding: ${euiThemeVars.euiSizeXS} ${euiThemeVars.euiSizeS}; `} color="text" // as far as I can tell all this currently adds is the correct active background color size="s" @@ -40,13 +41,9 @@ export const EmptyDimensionButton = ({ contentProps={{ css: css` justify-content: flex-start; + gap: ${euiThemeVars.euiSizeS}; padding: 0 !important; color: ${euiThemeVars.euiTextSubduedColor}; - gap: 0; - - .euiIcon { - margin-left: ${euiThemeVars.euiSizeS}; - } `, }} aria-label={ariaLabel} diff --git a/src/plugins/visualization_ui_components/public/components/dimension_buttons/trigger.tsx b/src/plugins/visualization_ui_components/public/components/dimension_buttons/trigger.tsx index 622faac8f766c..51e8b980fc63b 100644 --- a/src/plugins/visualization_ui_components/public/components/dimension_buttons/trigger.tsx +++ b/src/plugins/visualization_ui_components/public/components/dimension_buttons/trigger.tsx @@ -48,7 +48,6 @@ export const DimensionTrigger = ({ color={color} css={css` width: 100%; - padding: ${euiThemeVars.euiSizeXS} ${euiThemeVars.euiSizeS}; word-break: break-word; font-weight: ${euiThemeVars.euiFontWeightRegular}; `} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss index 3afcc0173ca2e..f2e3c26258182 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss @@ -60,8 +60,8 @@ } .lnsLayerPanel__group { - margin: (-$euiSizeS) (-$euiSize); - padding: $euiSizeS $euiSize; + margin: (-$euiSizeXS) (-$euiSize); + padding: $euiSizeXS $euiSize; } .lnsLayerPanel__styleEditor { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index f957886ce033a..683e052513ae2 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -648,6 +648,7 @@ export function LayerPanel( background-color: ${euiThemeVars.euiColorLightShade} !important; border-color: transparent !important; box-shadow: none !important; + padding: 0 ${euiThemeVars.euiSizeS}; `} > {preview.expression || preview.error ? ( diff --git a/x-pack/plugins/lens/public/shared_components/dataview_picker/trigger.tsx b/x-pack/plugins/lens/public/shared_components/dataview_picker/trigger.tsx index 77bf60fc247c9..0669b7b08f07e 100644 --- a/x-pack/plugins/lens/public/shared_components/dataview_picker/trigger.tsx +++ b/x-pack/plugins/lens/public/shared_components/dataview_picker/trigger.tsx @@ -101,7 +101,7 @@ export function TriggerButton({ fullWidth {...colorProp} {...rest} - textProps={{ style: { width: '100%' } }} + textProps={{ style: { width: '100%', lineHeight: '100%' } }} > diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/layer_header.tsx b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/layer_header.tsx index cb37fcbf5edfc..e695477d25d78 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/layer_header.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/layer_header.tsx @@ -235,6 +235,7 @@ const DataLayerHeaderTrigger = function ({ onClick={onClick} fullWidth size="s" + textProps={{ style: { lineHeight: '100%' } }} > <> From 6b3a29b4ec0b0da741a32f8152c7b4f42ddbac8d Mon Sep 17 00:00:00 2001 From: Marta Bondyra <4283304+mbondyra@users.noreply.github.com> Date: Tue, 11 Jul 2023 15:56:16 +0200 Subject: [PATCH 18/97] [Lens] fix drag and drop small styling details (#161121) ## Summary Fixes two subtle visual drag and drop thingies: 1. When reordering, the styles should look slightly differently: before: https://github.com/elastic/kibana/assets/4283304/b0f0d053-f6cc-414b-96cb-0b8ad892b613 after: https://github.com/elastic/kibana/assets/4283304/c52f8786-72e2-4ef3-a943-8050d7acf348 2. When picking up a dragging item, the whole dimension panel is jumping very slightly because we add `border`: before: https://github.com/elastic/kibana/assets/4283304/8efa71ec-d449-4dc9-8390-d4c33c62c1e0 after: https://github.com/elastic/kibana/assets/4283304/dbec7e64-5cb3-4b32-afcc-2c376cfda4a2 --- .../kbn-dom-drag-drop/src/sass/drag_drop.scss | 69 ++++++++++++------- .../src/sass/drag_drop_mixins.scss | 28 ++++++-- 2 files changed, 66 insertions(+), 31 deletions(-) diff --git a/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss b/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss index fecd5ee6bfbe0..ffea63cf94cef 100644 --- a/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss +++ b/packages/kbn-dom-drag-drop/src/sass/drag_drop.scss @@ -55,10 +55,6 @@ } } -.domDragDrop-isActiveGroup { - background-color: transparentize($euiColorVis0, .75); -} - // Drop area while hovering with item .domDragDrop-isActiveDropTarget:not(.domDragDrop__dropOverlayWrapper) { z-index: $domDragDropZLevel3; @@ -77,10 +73,14 @@ .domDragDrop-notCompatible:not(.domDragDrop__dropOverlayWrapper) { background-color: $euiColorHighlight !important; - border: $euiBorderWidthThin dashed $euiColorVis5 !important; + &:before { + border: $euiBorderWidthThin dashed $euiColorVis5 !important; + } &.domDragDrop-isActiveDropTarget { background-color: rgba(251, 208, 17, .25) !important; - border-color: $euiColorVis5 !important; + &:before { + border-color: $euiColorVis5 !important; + } } } @@ -138,21 +138,6 @@ $reorderItemMargin: $euiSizeS; } } -.domDragDrop--isDragStarted { - opacity: .5; -} - -// Draggable item when it is moving -.domDragDrop-isHidden { - opacity: 0; - .domDragDrop__keyboardHandler { - &:focus, - &:focus-within { - animation: none; - } - } -} - .domDragDrop__extraDrops { opacity: 0; visibility: hidden; @@ -182,12 +167,20 @@ $reorderItemMargin: $euiSizeS; width: 100%; height: 100%; background: $euiColorLightestShade; - border-radius: 0; - &:first-child, &:first-child .domDragDrop__extraDrop { + + .domDragDrop__extraDrop, + .domDragDrop__extraDrop:before { + border-radius: 0; + } + + &:first-child .domDragDrop__extraDrop, + &:first-child .domDragDrop__extraDrop:before { border-top-left-radius: $euiSizeXS; border-top-right-radius: $euiSizeXS; } - &:last-child, &:last-child .domDragDrop__extraDrop { + + &:last-child .domDragDrop__extraDrop, + &:last-child .domDragDrop__extraDrop:before { border-bottom-left-radius: $euiSizeXS; border-bottom-right-radius: $euiSizeXS; } @@ -233,3 +226,31 @@ $reorderItemMargin: $euiSizeS; @include mixinDomDroppableActiveHover($euiBorderWidthThick); } } + +.domDragDrop-isActiveGroup { + background-color: transparentize($euiColorVis0, .75); + .domDragDrop-isKeyboardReorderInProgress { + .domDragDrop--isDragStarted { + opacity: 1; + } + } + .domDragDrop-isActiveDropTarget, + .domDragDrop-isDropTarget { + background: $euiColorEmptyShade !important; + } +} + +.domDragDrop--isDragStarted { + opacity: .5; +} + +// Draggable item when it is moving +.domDragDrop-isHidden { + opacity: 0; + .domDragDrop__keyboardHandler { + &:focus, + &:focus-within { + animation: none; + } + } +} diff --git a/packages/kbn-dom-drag-drop/src/sass/drag_drop_mixins.scss b/packages/kbn-dom-drag-drop/src/sass/drag_drop_mixins.scss index fb495b4fcfba4..6e753b8b6db32 100644 --- a/packages/kbn-dom-drag-drop/src/sass/drag_drop_mixins.scss +++ b/packages/kbn-dom-drag-drop/src/sass/drag_drop_mixins.scss @@ -16,11 +16,6 @@ $domDragDropZLevel3: 3; cursor: grab; } -// Static styles for a drop area -@mixin mixinDomDroppable($borderWidth: $euiBorderWidthThin) { - border: $borderWidth dashed transparent; -} - // Hovering state for drag item and drop area @mixin mixinDomDragDropHover { &:hover { @@ -29,16 +24,35 @@ $domDragDropZLevel3: 3; } } +// Static styles for a drop area +@mixin mixinDomDroppable($borderWidth: $euiBorderWidthThin) { + &:before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + border-radius: $euiBorderRadius; + border: $borderWidth dashed transparent; + } +} + // Style for drop area when there's an item being dragged @mixin mixinDomDroppableActive($borderWidth: $euiBorderWidthThin) { background-color: transparentize($euiColorVis0, .9) !important; - border: $borderWidth dashed $euiColorVis0 !important; + &:before { + border-color: $euiColorVis0 !important; + } } // Style for drop area while hovering with item @mixin mixinDomDroppableActiveHover($borderWidth: $euiBorderWidthThin) { background-color: transparentize($euiColorVis0, .75) !important; - border: $borderWidth dashed $euiColorVis0 !important; + &:before { + border-color: $euiColorVis0 !important; + } } // Style for drop area that is not allowed for current item From 811fb7c4fdc2de23ebf3c5c24117fd69d263875d Mon Sep 17 00:00:00 2001 From: amyjtechwriter <61687663+amyjtechwriter@users.noreply.github.com> Date: Tue, 11 Jul 2023 15:08:31 +0100 Subject: [PATCH 19/97] [Docs] Try to make it clear drilldows only available in dashboard (#161469) ## Summary Issue [raised on Slack](https://elastic.slack.com/archives/C0D8P2XK5/p1688661541837369) that it was a bit unclear on our [docs page](https://www.elastic.co/guide/en/kibana/8.8/maps-create-filter-from-map.html#maps-spatial-filters) that to use drilldowns you had to embed your map in Dashboard, and can't be used from the Maps application. Original: Screenshot 2023-07-07 at 15 32 27 Updated: Screenshot 2023-07-07 at 11 47 45 --------- Co-authored-by: David Kilfoyle <41695641+kilfoyle@users.noreply.github.com> --- docs/maps/search.asciidoc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/maps/search.asciidoc b/docs/maps/search.asciidoc index 8575d9fda01ed..bfd293aa2352f 100644 --- a/docs/maps/search.asciidoc +++ b/docs/maps/search.asciidoc @@ -99,16 +99,18 @@ To filter your dashboard by your map bounds as you pan and zoom your map: A spatial filter narrows search results to documents that either intersect with, are within, or do not intersect with the specified geometry. -You can create spatial filters in two ways: - -* Click the tool icon image:maps/images/tools_icon.png[], and then draw a shape, bounding box, or distance on the map to define the spatial filter. -* Click *Filter by geometry* in a <>, and then use the feature's geometry for the spatial filter. - Spatial filters have the following properties: * *Geometry label* enables you to provide a meaningful name for your spatial filter. * *Spatial relation* determines the {ref}/query-dsl-geo-shape-query.html#geo-shape-spatial-relations[spatial relation operator] to use at search time. -* *Action* specifies whether to apply the filter to the current view or to a drilldown action. Only available when the map is a panel in a {kibana-ref}/dashboard.html[dashboard] with {kibana-ref}/drilldowns.html[drilldowns]. +* *Action* specifies whether to apply the filter to the current view or to a drilldown action. + +NOTE: {kibana-ref}/drilldowns.html[Drilldowns] are available only if the map is a panel in a {kibana-ref}/dashboard.html[dashboard], and not within the Maps application. + +You can create spatial filters in two ways: + +* Click the tool icon image:maps/images/tools_icon.png[tool icon], and then draw a shape, bounding box, or distance on the map to define the spatial filter. +* Click *Filter by geometry* in a <>, and then use the feature's geometry for the spatial filter. [role="screenshot"] image::maps/images/create_spatial_filter.png[] From 8f01d85966496812d8d047e31f78a0adf2d98c6b Mon Sep 17 00:00:00 2001 From: Adam Demjen Date: Tue, 11 Jul 2023 10:23:37 -0400 Subject: [PATCH 20/97] [8.10] [ESRE] Filter already attached pipelines (#161590) ## Summary Filter out pipelines from the existing pipeline selection dropdown that are already attached to the current index. This also updates the evaluation of the "Existing pipeline" option in the configuration panel. Example: 2 pipelines that are already attached are filtered from the dropdown; when attaching the 3rd one, the existing pipelines option is disabled. ![filter_attached_pipelines](https://github.com/elastic/kibana/assets/14224983/b401fcc4-e72a-4f62-ac37-a20dfab106f6) ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../ml_inference/ml_inference_logic.test.ts | 14 ++----------- .../ml_inference/ml_inference_logic.ts | 15 ++++++------- .../pipelines/ml_inference/utils.ts | 21 ------------------- .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 6 files changed, 10 insertions(+), 43 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts index 8f24399b2a9b8..7196749612877 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.test.ts @@ -297,7 +297,7 @@ describe('MlInferenceLogic', () => { }, ]); }); - it('returns disabled pipeline option if pipeline already attached', () => { + it('filters pipeline if pipeline already attached', () => { FetchMlInferencePipelineProcessorsApiLogic.actions.apiSuccess([ { modelId: 'test-model', @@ -324,17 +324,7 @@ describe('MlInferenceLogic', () => { }, }); - expect(MLInferenceLogic.values.existingInferencePipelines).toEqual([ - { - disabled: true, - disabledReason: expect.any(String), - pipelineName: 'unit-test', - modelType: '', - modelId: 'test-model', - sourceFields: ['body'], - indexFields: ['body'], - }, - ]); + expect(MLInferenceLogic.values.existingInferencePipelines).toEqual([]); }); }); describe('mlInferencePipeline', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts index e7b2cc71770a4..ac6d2f8401b00 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/ml_inference_logic.ts @@ -82,7 +82,7 @@ import { } from './types'; import { - getDisabledReason, + EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS, validateInferencePipelineConfiguration, validateInferencePipelineFields, validatePipelineNameIsAvailable, @@ -584,7 +584,9 @@ export const MLInferenceLogic = kea< mlInferencePipelinesData ) .map(([pipelineName, pipeline]): MLInferencePipelineOption | undefined => { - if (!pipeline) return undefined; + if (!pipeline || indexProcessorNames.includes(pipelineName)) return undefined; + + // Parse configuration from pipeline definition const pipelineParams = parseMlInferenceParametersFromPipeline(pipelineName, pipeline); if (!pipelineParams) return undefined; const { model_id: modelId, field_mappings: fieldMappings } = pipelineParams; @@ -593,11 +595,10 @@ export const MLInferenceLogic = kea< const missingSourceFields = sourceFields.filter((f) => !indexFields?.includes(f)) ?? []; const mlModel = supportedMLModels.find((model) => model.model_id === modelId); const modelType = mlModel ? getMLType(getMlModelTypesForModelConfig(mlModel)) : ''; - const disabledReason = getDisabledReason( - missingSourceFields, - indexProcessorNames, - pipelineName - ); + const disabledReason = + missingSourceFields.length > 0 + ? EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS(missingSourceFields.join(', ')) + : undefined; return { disabled: disabledReason !== undefined, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.ts index 27683135b5d02..332f885a3543d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.ts @@ -95,27 +95,6 @@ export const EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS = ( } ); -export const EXISTING_PIPELINE_DISABLED_PIPELINE_EXISTS = i18n.translate( - 'xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.disabledPipelineExistsDescription', - { - defaultMessage: 'This pipeline cannot be selected because it is already attached.', - } -); - -export const getDisabledReason = ( - missingSourceFields: string[], - indexProcessorNames: string[], - pipelineName: string -): string | undefined => { - if (missingSourceFields.length > 0) { - return EXISTING_PIPELINE_DISABLED_MISSING_SOURCE_FIELDS(missingSourceFields.join(', ')); - } else if (indexProcessorNames.includes(pipelineName)) { - return EXISTING_PIPELINE_DISABLED_PIPELINE_EXISTS; - } - - return undefined; -}; - export const MODEL_SELECT_PLACEHOLDER = i18n.translate( 'xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.model.placeholder', { defaultMessage: 'Select a model' } diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index ba8376cf9ca10..3994a4807487a 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -13143,7 +13143,6 @@ "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.docsLink": "Découvrez l'importation et l'utilisation des modèles de ML dans Enterprise Search", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.emptyValueError": "Champ obligatoire.", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.chooseLabel": "Choisir", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.disabledPipelineExistsDescription": "Ce pipeline ne peut pas être sélectionné car il est déjà attaché.", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.existingLabel": "Pipeline existant", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.newLabel": "Nouveau pipeline", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.placeholder": "Effectuez une sélection", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 9d30c9d27076c..b04bacbc52971 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -13142,7 +13142,6 @@ "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.docsLink": "エンタープライズ サーチでのMLモデルのインポートと使用の詳細", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.emptyValueError": "フィールドが必要です。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.chooseLabel": "選択", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.disabledPipelineExistsDescription": "このパイプラインはすでにアタッチされているため、選択できません。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.existingLabel": "既存のパイプライン", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.newLabel": "新しいパイプライン", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.placeholder": "1 つ選択してください", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e317ffc9db76a..d7efba31bcff9 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -13142,7 +13142,6 @@ "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.docsLink": "详细了解如何在 Enterprise Search 中导入并使用 ML 模型", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.emptyValueError": "“字段”必填。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.chooseLabel": "选择", - "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.disabledPipelineExistsDescription": "无法选择此管道,因为已附加该管道。", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.existingLabel": "现有管道", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.newLabel": "新建管道", "xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.existingPipeline.placeholder": "选择一个", From 9b6ad7280de61c0ed1471eda54b98a64d485b637 Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Tue, 11 Jul 2023 16:27:24 +0200 Subject: [PATCH 21/97] [Security Solution] Rule is created when the conditional logic "If alert matches a query" is left blank (#159690) ## Summary Original ticket: https://github.com/elastic/kibana/issues/156706 These changes prevent user from creating/updating the rule when alert filter is selected and query left blank on the rule's action page. We gonna show an error saying "A custom query is required." in this case. Screenshot 2023-06-14 at 14 36 35 Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../rules/rule_actions_field/index.tsx | 13 +++---- .../validate_rule_actions_field.ts | 4 ++- .../application/lib/value_validators.ts | 18 +++++++++- .../action_connector_form/action_form.tsx | 3 ++ .../action_type_form.tsx | 36 ++++++++++++++----- .../triggers_actions_ui/public/index.ts | 2 ++ 6 files changed, 60 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx index a524ad3929ea8..bfdc407fc551e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx @@ -119,7 +119,7 @@ export const RuleActionsField: React.FC = ({ }) => { const [fieldErrors, setFieldErrors] = useState(null); const form = useFormContext(); - const { isSubmitted, isSubmitting, isValid } = form; + const { isValid } = form; const { triggersActionsUi: { getActionForm }, } = useKibana().services; @@ -231,6 +231,7 @@ export const RuleActionsField: React.FC = ({ [field] ); + const isFormValidated = isValid !== undefined; const actionForm = useMemo( () => getActionForm({ @@ -251,6 +252,7 @@ export const RuleActionsField: React.FC = ({ hasSummary: true, notifyWhenSelectOptions: NOTIFY_WHEN_OPTIONS, defaultRuleFrequency: NOTIFICATION_DEFAULT_FREQUENCY, + disableErrorMessages: !isFormValidated, }), [ actions, @@ -262,18 +264,17 @@ export const RuleActionsField: React.FC = ({ setActionParamsProperty, setAlertActionsProperty, setActionAlertsFilterProperty, + isFormValidated, ] ); useEffect(() => { - if (isSubmitting || !field.errors.length) { - return setFieldErrors(null); - } - if (isSubmitted && !isSubmitting && isValid === false && field.errors.length) { + if (isValid === false) { const errorsString = field.errors.map(({ message }) => message).join('\n'); return setFieldErrors(errorsString); } - }, [isSubmitted, isSubmitting, field.isChangingValue, isValid, field.errors, setFieldErrors]); + return setFieldErrors(null); + }, [field.errors, isValid]); return ( diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/validate_rule_actions_field/validate_rule_actions_field.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/validate_rule_actions_field/validate_rule_actions_field.ts index 8d04ed43e0538..b881fd805e597 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/validate_rule_actions_field/validate_rule_actions_field.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/validate_rule_actions_field/validate_rule_actions_field.ts @@ -16,6 +16,7 @@ import type { RuleAction, ActionTypeRegistryContract, } from '@kbn/triggers-actions-ui-plugin/public'; +import { validateActionFilterQuery } from '@kbn/triggers-actions-ui-plugin/public'; import type { RuleActionsFormData } from '../../../../../detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form'; import type { ActionsStepRule } from '../../../../pages/detection_engine/rules/types'; import type { ValidationFunc, ERROR_CODE } from '../../../../../shared_imports'; @@ -29,8 +30,9 @@ export const validateSingleAction = async ( ): Promise => { const actionParamsErrors = await validateActionParams(actionItem, actionTypeRegistry); const mustacheErrors = validateMustache(actionItem.params); + const queryErrors = validateActionFilterQuery(actionItem); - return [...actionParamsErrors, ...mustacheErrors]; + return [...actionParamsErrors, ...mustacheErrors, ...(queryErrors ? [queryErrors] : [])]; }; export const validateRuleActionsField = diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts index e7b799519e1d0..96c01d201b0a0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts @@ -7,7 +7,23 @@ import { set } from '@kbn/safer-lodash-set'; import { constant, get } from 'lodash'; -import { UserConfiguredActionConnector, IErrorObject, Rule } from '../../types'; +import { i18n } from '@kbn/i18n'; +import { UserConfiguredActionConnector, IErrorObject, Rule, RuleAction } from '../../types'; + +const filterQueryRequiredError = i18n.translate( + 'xpack.triggersActionsUI.sections.actionTypeForm.error.requiredFilterQuery', + { + defaultMessage: 'A custom query is required.', + } +); + +export const validateActionFilterQuery = (actionItem: RuleAction): string | null => { + const query = actionItem.alertsFilter?.query; + if (query && !query.kql) { + return filterQueryRequiredError; + } + return null; +}; export function throwIfAbsent(message: string) { return (value: T | undefined): T => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index b7ff043d9727a..2bb623d423429 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -86,6 +86,7 @@ export interface ActionAccordionFormProps { defaultRuleFrequency?: RuleActionFrequency; ruleTypeId?: string; hasFieldsForAAD?: boolean; + disableErrorMessages?: boolean; } interface ActiveActionConnectorState { @@ -122,6 +123,7 @@ export const ActionForm = ({ ruleTypeId, producerId, hasFieldsForAAD, + disableErrorMessages, }: ActionAccordionFormProps) => { const { http, @@ -499,6 +501,7 @@ export const ActionForm = ({ producerId={producerId} ruleTypeId={ruleTypeId} hasFieldsForAAD={hasFieldsForAAD} + disableErrorMessages={disableErrorMessages} /> ); })} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx index d7fbb7f20169e..a506a6fc0ef27 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx @@ -63,6 +63,7 @@ import { ActionNotifyWhen } from './action_notify_when'; import { validateParamsForWarnings } from '../../lib/validate_params_for_warnings'; import { ActionAlertsFilterTimeframe } from './action_alerts_filter_timeframe'; import { ActionAlertsFilterQuery } from './action_alerts_filter_query'; +import { validateActionFilterQuery } from '../../lib/value_validators'; export type ActionTypeFormProps = { actionItem: RuleAction; @@ -92,6 +93,7 @@ export type ActionTypeFormProps = { producerId: string; ruleTypeId?: string; hasFieldsForAAD?: boolean; + disableErrorMessages?: boolean; } & Pick< ActionAccordionFormProps, | 'defaultActionGroupId' @@ -142,6 +144,7 @@ export const ActionTypeForm = ({ featureId, ruleTypeId, hasFieldsForAAD, + disableErrorMessages, }: ActionTypeFormProps) => { const { application: { capabilities }, @@ -247,13 +250,28 @@ export const ActionTypeForm = ({ useEffect(() => { (async () => { + if (disableErrorMessages) { + setActionParamsErrors({ errors: {} }); + return; + } const res: { errors: IErrorObject } = await actionTypeRegistry .get(actionItem.actionTypeId) ?.validateParams(actionItem.params); setActionParamsErrors(res); })(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [actionItem]); + }, [actionItem, disableErrorMessages]); + + const [queryError, setQueryError] = useState(null); + useEffect(() => { + (async () => { + if (disableErrorMessages) { + setQueryError(null); + return; + } + setQueryError(validateActionFilterQuery(actionItem)); + })(); + }, [actionItem, disableErrorMessages]); const canSave = hasSaveActionsCapability(capabilities); @@ -424,13 +442,15 @@ export const ActionTypeForm = ({ {showActionAlertsFilter && ( <> {!hideNotifyWhen && } - setActionAlertsFilterProperty('query', query, index)} - featureIds={[producerId as ValidFeatureId]} - appName={featureId!} - ruleTypeId={ruleTypeId} - /> + + setActionAlertsFilterProperty('query', query, index)} + featureIds={[producerId as ValidFeatureId]} + appName={featureId!} + ruleTypeId={ruleTypeId} + /> + { }; export { transformRule } from './application/lib/rule_api/common_transformations'; + +export { validateActionFilterQuery } from './application/lib/value_validators'; From 32b06938be2e182d823ea47e20599eff220805c7 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 11 Jul 2023 10:41:32 -0400 Subject: [PATCH 22/97] skip failing test suite (#161514) --- x-pack/test/functional/apps/infra/hosts_view.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/infra/hosts_view.ts b/x-pack/test/functional/apps/infra/hosts_view.ts index aa32e82b711e8..0e417d6306c5b 100644 --- a/x-pack/test/functional/apps/infra/hosts_view.ts +++ b/x-pack/test/functional/apps/infra/hosts_view.ts @@ -154,7 +154,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { return !!currentUrl.match(path); }); - describe('Hosts View', function () { + // Failing: See https://github.com/elastic/kibana/issues/161514 + describe.skip('Hosts View', function () { before(async () => { await Promise.all([ esArchiver.load('x-pack/test/functional/es_archives/infra/alerts'), From 9ab807796c2e7002edb575c406c6d7854211fc96 Mon Sep 17 00:00:00 2001 From: Jon Date: Tue, 11 Jul 2023 09:58:24 -0500 Subject: [PATCH 23/97] [ci] Add support for label `ci:build-serverless-image` (#161583) Adding the label `ci:build-serverless-image` will build and push the serverless image to our registry. The url will be available as an annotation at the top of Buildkite Closes https://github.com/elastic/kibana/issues/161562 --- .buildkite/scripts/build_kibana.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.buildkite/scripts/build_kibana.sh b/.buildkite/scripts/build_kibana.sh index 01810d26758c2..252daa79e0ea8 100755 --- a/.buildkite/scripts/build_kibana.sh +++ b/.buildkite/scripts/build_kibana.sh @@ -41,6 +41,32 @@ if is_pr_with_label "ci:build-cloud-image"; then EOF fi +if is_pr_with_label "ci:build-serverless-image"; then + echo "$KIBANA_DOCKER_PASSWORD" | docker login -u "$KIBANA_DOCKER_USERNAME" --password-stdin docker.elastic.co + GIT_ABBREV_COMMIT=${BUILDKITE_COMMIT:0:12} + node scripts/build \ + --skip-initialize \ + --skip-generic-folders \ + --skip-platform-folders \ + --skip-archives \ + --docker-images \ + --docker-namespace="kibana-ci" \ + --docker-tag="pr-$BUILDKITE_PULL_REQUEST-$GIT_ABBREV_COMMIT" \ + --docker-push \ + --skip-docker-ubi \ + --skip-docker-ubuntu \ + --skip-docker-cloud \ + --skip-docker-contexts + docker logout docker.elastic.co + + SERVERLESS_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" docker.elastic.co/kibana-ci/kibana-serverless) + buildkite-agent meta-data set pr_comment:deploy_cloud:head "* Kibana Serverless Image: \`$SERVERLESS_IMAGE\`" + cat << EOF | buildkite-agent annotate --style "info" --context kibana-serverless-image + + Kibana Serverless Image: \`$SERVERLESS_IMAGE\` +EOF +fi + echo "--- Archive Kibana Distribution" linuxBuild="$(find "$KIBANA_DIR/target" -name 'kibana-*-linux-x86_64.tar.gz')" installDir="$KIBANA_DIR/install/kibana" From a92432869f3c043d0f26719fe19323a10d51c7b0 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 11 Jul 2023 08:58:39 -0600 Subject: [PATCH 24/97] [embeddable] add should_fetch unit test (#161596) While messing around with time slider control and custom time ranges, I noticed shouldFetch$ is triggered (turns out search session id is changing - maybe a separate issue). During investigation, I found it difficult to explore without unit test for shouldFetch$. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../should_fetch.test.tsx | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/plugins/embeddable/public/lib/filterable_embeddable/should_fetch.test.tsx diff --git a/src/plugins/embeddable/public/lib/filterable_embeddable/should_fetch.test.tsx b/src/plugins/embeddable/public/lib/filterable_embeddable/should_fetch.test.tsx new file mode 100644 index 0000000000000..48dcf8f401d85 --- /dev/null +++ b/src/plugins/embeddable/public/lib/filterable_embeddable/should_fetch.test.tsx @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { BehaviorSubject, Subscription } from 'rxjs'; +import type { FilterableEmbeddableInput } from './types'; +import { shouldFetch$ } from './should_fetch'; + +describe('shouldFetch$', () => { + let shouldFetchCount = 0; + let subscription: Subscription; + let updateInput: (inputFragment: Partial) => void; + beforeAll(() => { + let input: FilterableEmbeddableInput = { + id: '1', + timeRange: { + to: 'now', + from: 'now-15m', + }, + }; + const subject = new BehaviorSubject(input); + updateInput = (inputFragment: Partial) => { + input = { + ...input, + ...inputFragment, + }; + subject.next(input); + }; + + subscription = shouldFetch$(subject, () => { + return input; + }).subscribe(() => { + shouldFetchCount++; + }); + }); + + afterAll(() => { + subscription.unsubscribe(); + }); + + test('should not fire on initial subscription', () => { + expect(shouldFetchCount).toBe(0); + }); + + test('should not fire when there are no changes', () => { + const initialCount = shouldFetchCount; + updateInput({}); + expect(shouldFetchCount).toBe(initialCount); + }); + + test('should fire when timeRange changes', () => { + const initialCount = shouldFetchCount; + updateInput({ + timeRange: { + to: 'now', + from: 'now-25m', + }, + }); + expect(shouldFetchCount).toBe(initialCount + 1); + }); +}); From 787491e2bb0e8c7bcba698effc5e6cacdd9721fe Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Tue, 11 Jul 2023 08:16:03 -0700 Subject: [PATCH 25/97] [Reporting] Allow Chromium to work by default in Docker (#149080) ## Summary Closes https://github.com/elastic/kibana/issues/129148 ### Checklist Delete any items that are not applicable to this PR. - [x] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ## Release Note Fixed a bug where Kibana Reporting would not work in Elastic Docker without adding a special setting in kibana.yml. --- ...porting-production-considerations.asciidoc | 9 +++--- .../templates/base/Dockerfile | 1 + .../templates/ironbank/Dockerfile | 1 + .../default_chromium_sandbox_disabled.test.ts | 29 +++++++++++++++++++ .../default_chromium_sandbox_disabled.ts | 17 +++++++---- 5 files changed, 48 insertions(+), 9 deletions(-) diff --git a/docs/user/production-considerations/reporting-production-considerations.asciidoc b/docs/user/production-considerations/reporting-production-considerations.asciidoc index db972e1bbf368..43461d9d9d7ee 100644 --- a/docs/user/production-considerations/reporting-production-considerations.asciidoc +++ b/docs/user/production-considerations/reporting-production-considerations.asciidoc @@ -28,14 +28,15 @@ For an additional layer of security, use the sandbox. The Chromium sandbox uses [[reporting-linux-sandbox]] ==== Linux sandbox The Linux sandbox depends on user namespaces, which were introduced with the 3.8 Linux kernel. However, many -distributions don't have user namespaces enabled by default, or they require the CAP_SYS_ADMIN capability. The {report-features} -automatically disable the sandbox when it is running on Debian because additional steps are required to enable -unprivileged usernamespaces. In these situations, you'll see the following message in your {kib} startup logs: +distributions don't support or allow non-privileged processes to create user namespaces, or they require the CAP_SYS_ADMIN capability. The {report-features} +automatically disable the sandbox when it detects it is running on systems where it is not enabled. +Without explicitly setting `xpack.screenshotting.browser.chromium.disableSandbox: false` in `kibana.yml`, +the {report-features} may detect that it can't be enabled. In the event it is automatically disabled, you'll see the following message in your {kib} startup logs: `Chromium sandbox provides an additional layer of protection, but is not supported for your OS. Automatically setting 'xpack.screenshotting.browser.chromium.disableSandbox: true'.` Reporting automatically enables the Chromium sandbox at startup when a supported OS is detected. However, if your kernel is 3.8 or newer, it's -recommended to set `xpack.screenshotting.browser.chromium.disableSandbox: false` in your `kibana.yml` to explicitly enable usernamespaces. +recommended to set `xpack.screenshotting.browser.chromium.disableSandbox: false` in your `kibana.yml` to explicitly enable the sandbox. [float] [[reporting-docker-sandbox]] diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile index beeed1d12dd04..a44fae27c4265 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile @@ -115,6 +115,7 @@ WORKDIR /usr/share/kibana RUN ln -s /usr/share/kibana /opt/kibana {{! Please notify @elastic/kibana-security if you want to remove or change this environment variable. }} +{{! Kibana applications may depend on the ELASTIC_CONTAINER value. Screenshotting uses this to conditionally disable the Chromium sandbox when launching Puppeteer. }} ENV ELASTIC_CONTAINER true ENV PATH=/usr/share/kibana/bin:$PATH diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/Dockerfile b/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/Dockerfile index 184d2cfb9414d..a0d3a49a19a89 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/Dockerfile +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/ironbank/Dockerfile @@ -52,6 +52,7 @@ WORKDIR /usr/share/kibana RUN ln -s /usr/share/kibana /opt/kibana {{! Please notify @elastic/kibana-security if you want to remove or change this environment variable. }} +{{! Kibana applications may depend on the ELASTIC_CONTAINER value. Screenshotting uses this to conditionally disable the Chromium sandbox when launching Puppeteer. }} ENV ELASTIC_CONTAINER true ENV PATH=/usr/share/kibana/bin:$PATH diff --git a/x-pack/plugins/screenshotting/server/config/default_chromium_sandbox_disabled.test.ts b/x-pack/plugins/screenshotting/server/config/default_chromium_sandbox_disabled.test.ts index 7204230ef5160..0b5f503e86921 100644 --- a/x-pack/plugins/screenshotting/server/config/default_chromium_sandbox_disabled.test.ts +++ b/x-pack/plugins/screenshotting/server/config/default_chromium_sandbox_disabled.test.ts @@ -33,3 +33,32 @@ describe('getDefaultChromiumSandboxDisabled', () => { ); }); }); + +describe('Docker', () => { + const mockOs = { os: 'linux', dist: 'Ubuntu Linux', release: '20.01' }; + + it('Non-Docker', async () => { + (getos as jest.Mock).mockImplementation((cb) => cb(null, mockOs)); + + await expect(getDefaultChromiumSandboxDisabled()).resolves.toHaveProperty( + 'disableSandbox', + false + ); + }); + + it('Elastic Docker container', async () => { + // setup: mock environment variables + const env = { ...process.env }; + process.env.ELASTIC_CONTAINER = 'true'; + + (getos as jest.Mock).mockImplementation((cb) => cb(null, mockOs)); + + await expect(getDefaultChromiumSandboxDisabled()).resolves.toHaveProperty( + 'disableSandbox', + true + ); + + // cleanup: restore the environment variables + process.env = env; + }); +}); diff --git a/x-pack/plugins/screenshotting/server/config/default_chromium_sandbox_disabled.ts b/x-pack/plugins/screenshotting/server/config/default_chromium_sandbox_disabled.ts index 4461b53bf0fcf..34986e804f45a 100644 --- a/x-pack/plugins/screenshotting/server/config/default_chromium_sandbox_disabled.ts +++ b/x-pack/plugins/screenshotting/server/config/default_chromium_sandbox_disabled.ts @@ -11,7 +11,7 @@ import { promisify } from 'util'; const getOs = promisify(getOsSync); const distroSupportsUnprivilegedUsernamespaces = (distro: string) => { - // Debian 7 and 8 don't support usernamespaces by default + // Debian 7 and 8 don't support user namespaces by default // this should be reevaluated when Debian 9 is available if (distro.toLowerCase() === 'debian') { return false; @@ -40,8 +40,15 @@ interface OsSummary { export async function getDefaultChromiumSandboxDisabled(): Promise { const os = await getOs(); - return { - os, - disableSandbox: os.os === 'linux' && !distroSupportsUnprivilegedUsernamespaces(os.dist), - }; + let enableSandbox: boolean; + if (process.env.ELASTIC_CONTAINER) { + // In the Elastic Docker image, user namespaces is not supported. This is relatively safe since Docker + // provides a level of isolation. In addition, Chromium is only used to open Kibana URLs within the + // deployment, which makes it relatively locked down from being able to exploit Chromium. + enableSandbox = false; + } else { + enableSandbox = os.os !== 'linux' || distroSupportsUnprivilegedUsernamespaces(os.dist); + } + + return { os, disableSandbox: !enableSandbox }; } From 70ed2004343561fcc162d287d231b01d8803eab0 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 11 Jul 2023 17:55:49 +0200 Subject: [PATCH 26/97] [Synthetics] De-dupe overview status request on load (#161627) --- .../journeys/overview_scrolling.journey.ts | 22 +++++++++++++++++++ .../hooks/use_overview_status.ts | 12 +++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/synthetics/e2e/synthetics/journeys/overview_scrolling.journey.ts b/x-pack/plugins/synthetics/e2e/synthetics/journeys/overview_scrolling.journey.ts index 2936c33d8c44c..abc9204eb64d1 100644 --- a/x-pack/plugins/synthetics/e2e/synthetics/journeys/overview_scrolling.journey.ts +++ b/x-pack/plugins/synthetics/e2e/synthetics/journeys/overview_scrolling.journey.ts @@ -21,7 +21,15 @@ journey('OverviewScrolling', async ({ page, params }) => { const syntheticsApp = syntheticsAppPageProvider({ page, kibanaUrl: params.kibanaUrl }); const retry: RetryService = params.getService('retry'); + const listOfRequests: string[] = []; + before(async () => { + page.on('request', (request) => { + const url = request.url(); + if (url.includes('/synthetics/') || url.includes('/uptime/')) { + listOfRequests.push(request.url()); + } + }); await enableMonitorManagedViaApi(params.kibanaUrl); await cleanTestMonitors(params); @@ -48,6 +56,20 @@ journey('OverviewScrolling', async ({ page, params }) => { expect(await invalid.isVisible()).toBeFalsy(); }); + step('validates de-duplicate requests', async () => { + await page.waitForSelector(`text="test monitor 0"`); + + const assertUnique = (value: string) => { + expect(listOfRequests.filter((req) => req.includes(value)).length).toBe(1); + }; + assertUnique('/overview_status'); + assertUnique('/overview?'); + assertUnique('/service/monitors'); + assertUnique('/monitor/filters'); + + expect(listOfRequests.length).toBe(16); + }); + step('scroll until you see showing all monitors', async () => { const gridItems = await page.locator(`[data-test-subj="syntheticsOverviewGridItem"]`); await page.waitForSelector(`text="test monitor 0"`); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_overview_status.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_overview_status.ts index ed99ec8161765..b06b66f8a5a73 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_overview_status.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/hooks/use_overview_status.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useEffect, useCallback } from 'react'; +import { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useSyntheticsRefreshContext } from '../../../contexts/synthetics_refresh_context'; import { selectOverviewPageState } from '../../../state'; @@ -23,21 +23,19 @@ export function useOverviewStatus({ scopeStatusByLocation }: { scopeStatusByLoca const { lastRefresh } = useSyntheticsRefreshContext(); const dispatch = useDispatch(); - const reload = useCallback(() => { - dispatch(fetchOverviewStatusAction.get({ pageState, scopeStatusByLocation })); - }, [dispatch, pageState, scopeStatusByLocation]); useEffect(() => { if (loaded) { dispatch(quietFetchOverviewStatusAction.get({ pageState, scopeStatusByLocation })); } else { - reload(); + dispatch(fetchOverviewStatusAction.get({ pageState, scopeStatusByLocation })); } - }, [dispatch, reload, lastRefresh, pageState, loaded, scopeStatusByLocation]); + // loaded is omitted from the dependency array because it is not used in the callback + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [dispatch, lastRefresh, pageState, scopeStatusByLocation]); return { status, error, - reload, }; } From 08a57b9e3a570329c4f8051dcf195fe80e691eb3 Mon Sep 17 00:00:00 2001 From: christineweng <18648970+christineweng@users.noreply.github.com> Date: Tue, 11 Jul 2023 11:13:02 -0500 Subject: [PATCH 27/97] [Security Solution] Add validations for insight form in timeline and rules (#161034) ## Summary Currently user can add a note in timeline with invalid markdown syntax in insight forms. Same goes to the investigation guide in rule creation -> About. ### Before **In timeline -> Notes** ![image](https://github.com/elastic/kibana/assets/18648970/33b05592-f97a-41d8-a394-fc111f4cc039) **On rules -> about** ![image](https://github.com/elastic/kibana/assets/18648970/ca09ac1a-7798-4b13-820b-85e5cf0f61c7) ### After **Timeline -> Notes** Add note button should be disabled if markdown is invalid ![image](https://github.com/elastic/kibana/assets/18648970/d34b0ab1-c39b-443a-a309-00aba251731e) **On rules -> about** Field is red if markdown is invalid ![image](https://github.com/elastic/kibana/assets/18648970/850f9f4a-71a7-44f8-a9e1-bbfbdb07b0dd) ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/markdown_editor/editor.tsx | 25 ++++++++++++++++--- .../components/markdown_editor/eui_form.tsx | 6 +++-- .../__snapshots__/new_note.test.tsx.snap | 1 + .../components/notes/add_note/index.test.tsx | 1 + .../components/notes/add_note/index.tsx | 8 +++--- .../notes/add_note/new_note.test.tsx | 16 ++++++++++-- .../components/notes/add_note/new_note.tsx | 4 ++- 7 files changed, 49 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/editor.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/editor.tsx index 79802dae16049..0137e6dedc536 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/editor.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/editor.tsx @@ -30,6 +30,7 @@ interface MarkdownEditorProps { dataTestSubj?: string; height?: number; autoFocusDisabled?: boolean; + setIsMarkdownInvalid: (value: boolean) => void; } type EuiMarkdownEditorRef = ElementRef; @@ -41,11 +42,27 @@ export interface MarkdownEditorRef { } const MarkdownEditorComponent = forwardRef( - ({ onChange, value, ariaLabel, editorId, dataTestSubj, height, autoFocusDisabled }, ref) => { + ( + { + onChange, + value, + ariaLabel, + editorId, + dataTestSubj, + height, + autoFocusDisabled, + setIsMarkdownInvalid, + }, + ref + ) => { const [markdownErrorMessages, setMarkdownErrorMessages] = useState([]); - const onParse = useCallback((err, { messages }) => { - setMarkdownErrorMessages(err ? [err] : messages); - }, []); + const onParse = useCallback( + (err, { messages }) => { + setMarkdownErrorMessages(err ? [err] : messages); + setIsMarkdownInvalid(err ? true : false); + }, + [setIsMarkdownInvalid] + ); const editorRef = useRef(null); useEffect(() => { diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/eui_form.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/eui_form.tsx index 9554b5bba4e5b..c44ff696f2020 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/eui_form.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/eui_form.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { forwardRef } from 'react'; +import React, { forwardRef, useState } from 'react'; import styled from 'styled-components'; import type { EuiMarkdownEditorProps } from '@elastic/eui'; import { EuiFormRow, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; @@ -34,6 +34,7 @@ export const MarkdownEditorForm = React.memo( forwardRef( ({ id, field, dataTestSubj, idAria, bottomRightContent }, ref) => { const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); + const [isMarkdownInvalid, setIsMarkdownInvalid] = useState(false); return ( @@ -54,6 +55,7 @@ export const MarkdownEditorForm = React.memo( onChange={field.setValue} value={field.value as string} data-test-subj={`${dataTestSubj}-markdown-editor`} + setIsMarkdownInvalid={setIsMarkdownInvalid} /> {bottomRightContent && ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/__snapshots__/new_note.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/__snapshots__/new_note.test.tsx.snap index 32e17a19045b1..3e3f4bd1e99cf 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/__snapshots__/new_note.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/__snapshots__/new_note.test.tsx.snap @@ -10,6 +10,7 @@ exports[`NewNote renders correctly 1`] = ` dataTestSubj="add-a-note" height={200} onChange={[MockFunction]} + setIsMarkdownInvalid={[MockFunction]} value="The contents of a new note" /> diff --git a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/index.test.tsx index e883ea10b0a6c..fe1f23c29028b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/index.test.tsx @@ -41,6 +41,7 @@ describe('AddNote', () => { newNote: note, onCancelAddNote: jest.fn(), updateNewNote: jest.fn(), + setIsMarkdownInvalid: jest.fn(), }; test('renders correctly', () => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/index.tsx index 9e216b24f7843..31df17fa40046 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/index.tsx @@ -12,7 +12,7 @@ import { EuiFlexItem, EuiScreenReaderOnly, } from '@elastic/eui'; -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import styled from 'styled-components'; import { useDispatch } from 'react-redux'; @@ -56,6 +56,7 @@ export const AddNote = React.memo<{ }>(({ associateNote, newNote, onCancelAddNote, updateNewNote, autoFocusDisabled = false }) => { const dispatch = useDispatch(); const authenticatedUser = useCurrentUser(); + const [isMarkdownInvalid, setIsMarkdownInvalid] = useState(false); const updateNote = useCallback( (note: Note) => dispatch(appActions.updateNote({ note })), [dispatch] @@ -88,8 +89,8 @@ export const AddNote = React.memo<{ ); const isAddNoteDisabled = useMemo(() => { - return newNote.trim().length === 0; - }, [newNote]); + return newNote.trim().length === 0 || isMarkdownInvalid; + }, [newNote, isMarkdownInvalid]); return ( @@ -102,6 +103,7 @@ export const AddNote = React.memo<{ noteInputHeight={200} updateNewNote={updateNewNote} autoFocusDisabled={autoFocusDisabled} + setIsMarkdownInvalid={setIsMarkdownInvalid} /> {onCancelAddNote != null ? ( diff --git a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/new_note.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/new_note.test.tsx index 4dd90b877e962..0a4659b8d18b9 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/new_note.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/new_note.test.tsx @@ -15,13 +15,25 @@ describe('NewNote', () => { test('renders correctly', () => { const wrapper = shallow( - + ); expect(wrapper).toMatchSnapshot(); }); test('it renders a text area containing the contents of a new (raw) note', () => { - const wrapper = mount(); + const wrapper = mount( + + ); expect( wrapper.find('[data-test-subj="add-a-note"] .euiMarkdownEditorDropZone').first().text() diff --git a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/new_note.tsx b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/new_note.tsx index 4d02a1e8c74c1..a6a3c5c173ef6 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/new_note.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/notes/add_note/new_note.tsx @@ -25,7 +25,8 @@ export const NewNote = React.memo<{ note: string; updateNewNote: UpdateInternalNewNote; autoFocusDisabled?: boolean; -}>(({ note, noteInputHeight, updateNewNote, autoFocusDisabled = false }) => { + setIsMarkdownInvalid: (value: boolean) => void; +}>(({ note, noteInputHeight, updateNewNote, autoFocusDisabled = false, setIsMarkdownInvalid }) => { return ( ); From 586e8db0d2e9cac3c774de277c07c93cace060eb Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Tue, 11 Jul 2023 12:26:00 -0400 Subject: [PATCH 28/97] chore(slo): update open api spec (#161670) --- .../docs/openapi/slo/bundled.yaml | 990 +++++------------- .../schemas/base_composite_slo_response.yaml | 10 +- .../schemas/composite_slo_response.yaml | 12 +- .../schemas/create_composite_slo_request.yaml | 11 +- .../schemas/create_slo_request.yaml | 18 +- .../indicator_properties_custom_metric.yaml | 8 +- .../slo/components/schemas/slo_response.yaml | 20 +- .../slo/components/schemas/time_window.yaml | 16 + .../schemas/time_window_calendar_aligned.yaml | 15 - .../schemas/time_window_rolling.yaml | 15 - .../schemas/update_composite_slo_request.yaml | 11 +- .../schemas/update_slo_request.yaml | 18 +- .../docs/openapi/slo/entrypoint.yaml | 32 +- 13 files changed, 354 insertions(+), 822 deletions(-) create mode 100644 x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window.yaml delete mode 100644 x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window_calendar_aligned.yaml delete mode 100644 x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window_rolling.yaml diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml index f4ef3a5991387..533d06a67e54b 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml @@ -8,269 +8,15 @@ info: license: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license -servers: - - url: http://localhost:5601 - description: local -security: - - basicAuth: [] - - apiKeyAuth: [] tags: - name: slo description: SLO APIs enable you to define, manage and track service-level objectives - name: composite slo description: Composite SLO APIs enable you to define, manage and track a group of SLOs. +servers: + - url: http://localhost:5601 + description: local paths: - /s/{spaceId}/api/observability/composite_slos: - post: - summary: Creates a Composite SLO - operationId: createCompositeSlo - description: | - You must have `all` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. - tags: - - composite slo - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/space_id' - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/create_composite_slo_request' - responses: - '200': - description: Successful request - content: - application/json: - schema: - $ref: '#/components/schemas/create_composite_slo_response' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/400_response' - '401': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/401_response' - '403': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/403_response' - '409': - description: Conflict - The Composite SLO id already exists - content: - application/json: - schema: - $ref: '#/components/schemas/409_response' - get: - summary: Retrieves a paginated list of composite SLOs with summary - operationId: findCompositeSlo - description: | - You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. - tags: - - composite slo - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/space_id' - - name: page - in: query - description: The page number to return - schema: - type: integer - default: 1 - example: 1 - - name: perPage - in: query - description: The number of SLOs to return per page - schema: - type: integer - default: 25 - example: 20 - - name: sortBy - in: query - description: Sort by field - schema: - type: string - enum: - - creationTime - default: creationTime - example: creationTime - - name: sortDirection - in: query - description: Sort order - schema: - type: string - enum: - - asc - - desc - default: asc - example: asc - responses: - '200': - description: Successful request - content: - application/json: - schema: - $ref: '#/components/schemas/find_composite_slo_response' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/400_response' - '401': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/401_response' - '403': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/403_response' - '404': - description: Not found response - content: - application/json: - schema: - $ref: '#/components/schemas/404_response' - /s/{spaceId}/api/observability/composite_slos/{compositeSloId}: - get: - summary: Retrieves a composite SLO - operationId: getCompositeSlo - description: | - You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. - tags: - - composite slo - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/space_id' - - $ref: '#/components/parameters/composite_slo_id' - responses: - '200': - description: Successful request - content: - application/json: - schema: - $ref: '#/components/schemas/composite_slo_response' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/400_response' - '401': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/401_response' - '403': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/403_response' - '404': - description: Not found response - content: - application/json: - schema: - $ref: '#/components/schemas/404_response' - put: - summary: Updates a composite SLO - operationId: updateCompositeSlo - description: | - You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. - tags: - - composite slo - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/space_id' - - $ref: '#/components/parameters/composite_slo_id' - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/update_composite_slo_request' - responses: - '200': - description: Successful request - content: - application/json: - schema: - $ref: '#/components/schemas/base_composite_slo_response' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/400_response' - '401': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/401_response' - '403': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/403_response' - '404': - description: Not found response - content: - application/json: - schema: - $ref: '#/components/schemas/404_response' - delete: - summary: Deletes a composite SLO - operationId: deleteCompositeSlo - description: | - You must have the `write` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. - tags: - - composite slo - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/space_id' - - $ref: '#/components/parameters/composite_slo_id' - responses: - '204': - description: Successful request - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/400_response' - '401': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/401_response' - '403': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/403_response' - '404': - description: Not found response - content: - application/json: - schema: - $ref: '#/components/schemas/404_response' /s/{spaceId}/api/observability/slos: post: summary: Creates an SLO. @@ -602,448 +348,98 @@ paths: $ref: '#/components/schemas/400_response' '401': description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/401_response' - '403': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/403_response' - '404': - description: Not found response - content: - application/json: - schema: - $ref: '#/components/schemas/404_response' - /s/{spaceId}/internal/observability/slos/_historical_summary: - post: - summary: Retrieves the historical summary for a list of SLOs - operationId: historicalSummary - description: | - You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. - tags: - - slo - parameters: - - $ref: '#/components/parameters/kbn_xsrf' - - $ref: '#/components/parameters/space_id' - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/historical_summary_request' - responses: - '200': - description: Successful request - content: - application/json: - schema: - $ref: '#/components/schemas/historical_summary_response' - '400': - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/400_response' - '401': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/401_response' - '403': - description: Unauthorized response - content: - application/json: - schema: - $ref: '#/components/schemas/403_response' -components: - securitySchemes: - basicAuth: - type: http - scheme: basic - apiKeyAuth: - type: apiKey - in: header - name: ApiKey - parameters: - kbn_xsrf: - schema: - type: string - in: header - name: kbn-xsrf - description: Cross-site request forgery protection - required: true - space_id: - in: path - name: spaceId - description: An identifier for the space. If `/s/` and the identifier are omitted from the path, the default space is used. - required: true - schema: - type: string - example: default - composite_slo_id: - in: path - name: compositeSloId - description: An identifier for the composite slo. - required: true - schema: - type: string - example: 9c235211-6834-11ea-a78c-6feb38a34414 - slo_id: - in: path - name: sloId - description: An identifier for the slo. - required: true - schema: - type: string - example: 9c235211-6834-11ea-a78c-6feb38a34414 - schemas: - time_window_rolling: - title: Rolling - required: - - duration - - isRolling - description: Defines properties for rolling time window - type: object - properties: - duration: - description: the duration formatted as {duration}{unit} - type: string - example: 28d - isRolling: - description: Indicates a rolling time window - type: boolean - example: true - budgeting_method: - title: Budgeting method - type: string - description: The budgeting method to use when computing the rollup data. - enum: - - occurrences - - timeslices - example: occurrences - composite_method: - title: Composite method - type: string - description: The composite method to use for the composite SLO. - enum: - - weightedAverage - example: weightedAverage - objective: - title: Objective - required: - - target - description: Defines properties for the SLO objective - type: object - properties: - target: - description: the target objective between 0 and 1 excluded - type: number - example: 0.99 - timeslicesTarget: - description: the target objective for each slice when using a timeslices budgeting method - type: number - example: 0.995 - timeslicesWindow: - description: the duration of each slice when using a timeslices budgeting method, as {duraton}{unit} - type: string - example: 5m - weighted_composite_sources: - title: Weighted sources - description: An array of source SLO to use for the weighted average composite. - type: array - items: - type: object - required: - - id - - revision - - weight - properties: - id: - description: The id of the SLO. - type: string - example: 8853df00-ae2e-11ed-90af-09bb6422b258 - revision: - description: The revision number of the SLO. - type: number - example: 2 - weight: - description: The weight to apply to this SLO. - type: number - example: 3 - error_budget: - title: Error budget - type: object - properties: - initial: - type: number - description: The initial error budget, as 1 - objective - example: 0.02 - consumed: - type: number - description: The error budget consummed, as a percentage of the initial value. - example: 0.8 - remaining: - type: number - description: The error budget remaining, as a percentage of the initial value. - example: 0.2 - isEstimated: - type: boolean - description: Only for SLO defined with occurrences budgeting method and calendar aligned time window. - example: true - summary: - title: Summary - type: object - description: The SLO computed data - properties: - status: - type: string - enum: - - NO_DATA - - HEALTHY - - DEGRADING - - VIOLATED - example: HEALTHY - sliValue: - type: number - example: 0.9836 - errorBudget: - $ref: '#/components/schemas/error_budget' - composite_slo_response: - title: Composite SLO with summary response - type: object - properties: - id: - description: The identifier of the composite SLO. - type: string - example: 8853df00-ae2e-11ed-90af-09bb6422b258 - name: - description: The name of the composite SLO. - type: string - example: My Service SLO - timeWindow: - $ref: '#/components/schemas/time_window_rolling' - budgetingMethod: - $ref: '#/components/schemas/budgeting_method' - compositeMethod: - $ref: '#/components/schemas/composite_method' - objective: - $ref: '#/components/schemas/objective' - sources: - oneOf: - - $ref: '#/components/schemas/weighted_composite_sources' - summary: - $ref: '#/components/schemas/summary' - createdAt: - description: The creation date - type: string - example: '2023-01-12T10:03:19.000Z' - updatedAt: - description: The last update date - type: string - example: '2023-01-12T10:03:19.000Z' - find_composite_slo_response: - title: Find composite SLO response - description: A paginated response of composite SLOs matching the query. - type: object - properties: - page: - type: number - example: 1 - perPage: - type: number - example: 25 - total: - type: number - example: 34 - results: - type: array - items: - $ref: '#/components/schemas/composite_slo_response' - 400_response: - title: Bad request - type: object - required: - - statusCode - - error - - message - properties: - statusCode: - type: number - example: 400 - error: - type: string - example: Bad Request - message: - type: string - example: 'Invalid value ''foo'' supplied to: [...]' - 401_response: - title: Unauthorized - type: object - required: - - statusCode - - error - - message - properties: - statusCode: - type: number - example: 401 - error: - type: string - example: Unauthorized - message: - type: string - example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" - 403_response: - title: Unauthorized - type: object - required: - - statusCode - - error - - message - properties: - statusCode: - type: number - example: 403 - error: - type: string - example: Unauthorized - message: - type: string - example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" - 404_response: - title: Not found - type: object - required: - - statusCode - - error - - message - properties: - statusCode: - type: number - example: 404 - error: - type: string - example: Not Found - message: - type: string - example: SLO [3749f390-03a3-11ee-8139-c7ff60a1692d] not found - create_composite_slo_request: - title: Create composite SLO request - description: | - The create Composite SLO API request body. The provided source SLOs must exists and their budgeting method and time window must match the one from the composite SLO. - type: object - required: - - name - - timeWindow - - budgetingMethod - - compositeMethod - - objective - - sources - properties: - id: - description: A unique identifier for the composite SLO. Must be between 8 and 36 chars - type: string - example: my-super-composite-slo-id - name: - description: A name for the composite SLO. - type: string - timeWindow: - $ref: '#/components/schemas/time_window_rolling' - budgetingMethod: - $ref: '#/components/schemas/budgeting_method' - compositeMethod: - $ref: '#/components/schemas/composite_method' - objective: - $ref: '#/components/schemas/objective' - sources: - oneOf: - - $ref: '#/components/schemas/weighted_composite_sources' - create_composite_slo_response: - title: Create composite SLO response - type: object - required: - - id - properties: - id: - type: string - example: 8853df00-ae2e-11ed-90af-09bb6422b258 - 409_response: - title: Conflict - type: object - required: - - statusCode - - error - - message - properties: - statusCode: - type: number - example: 409 - error: - type: string - example: Conflict - message: - type: string - example: SLO [d077e940-1515-11ee-9c50-9d096392f520] already exists - update_composite_slo_request: - title: Update composite SLO request - description: | - The update composite SLO API request body. The provided source SLOs must exists and their budgeting method and time window must match the one from the composite SLO. - type: object - properties: - id: - description: A unique identifier for the composite SLO. Must be between 8 and 36 chars - type: string - example: my-super-composite-slo-id - name: - description: A name for the composite SLO. - type: string - timeWindow: - $ref: '#/components/schemas/time_window_rolling' - budgetingMethod: - $ref: '#/components/schemas/budgeting_method' - compositeMethod: - $ref: '#/components/schemas/composite_method' - objective: - $ref: '#/components/schemas/objective' - sources: - oneOf: - - $ref: '#/components/schemas/weighted_composite_sources' - base_composite_slo_response: - title: Composite SLO response - type: object - properties: - id: - description: The identifier of the composite SLO. - type: string - example: 8853df00-ae2e-11ed-90af-09bb6422b258 - name: - description: The name of the composite SLO. - type: string - example: My Service SLO - timeWindow: - $ref: '#/components/schemas/time_window_rolling' - budgetingMethod: - $ref: '#/components/schemas/budgeting_method' - compositeMethod: - $ref: '#/components/schemas/composite_method' - objective: - $ref: '#/components/schemas/objective' - sources: - oneOf: - - $ref: '#/components/schemas/weighted_composite_sources' - createdAt: - description: The creation date - type: string - example: '2023-01-12T10:03:19.000Z' - updatedAt: - description: The last update date - type: string - example: '2023-01-12T10:03:19.000Z' + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' + '404': + description: Not found response + content: + application/json: + schema: + $ref: '#/components/schemas/404_response' + /s/{spaceId}/internal/observability/slos/_historical_summary: + post: + summary: Retrieves the historical summary for a list of SLOs + operationId: historicalSummary + description: | + You must have the `read` privileges for the **SLOs** feature in the **Observability** section of the Kibana feature privileges. + tags: + - slo + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + - $ref: '#/components/parameters/space_id' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/historical_summary_request' + responses: + '200': + description: Successful request + content: + application/json: + schema: + $ref: '#/components/schemas/historical_summary_response' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/400_response' + '401': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/401_response' + '403': + description: Unauthorized response + content: + application/json: + schema: + $ref: '#/components/schemas/403_response' +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + apiKeyAuth: + type: apiKey + in: header + name: ApiKey + parameters: + kbn_xsrf: + schema: + type: string + in: header + name: kbn-xsrf + description: Cross-site request forgery protection + required: true + space_id: + in: path + name: spaceId + description: An identifier for the space. If `/s/` and the identifier are omitted from the path, the default space is used. + required: true + schema: + type: string + example: default + slo_id: + in: path + name: sloId + description: An identifier for the slo. + required: true + schema: + type: string + example: 9c235211-6834-11ea-a78c-6feb38a34414 + schemas: indicator_properties_custom_kql: title: Custom KQL required: @@ -1248,6 +644,10 @@ components: description: The field of the metric. type: string example: processor.processed + filter: + description: The filter to apply to the metric. + type: string + example: 'processor.outcome: "success"' equation: description: The equation to calculate the "good" metric. type: string @@ -1285,6 +685,10 @@ components: description: The field of the metric. type: string example: processor.processed + filter: + description: The filter to apply to the metric. + type: string + example: 'processor.outcome: *' equation: description: The equation to calculate the "total" metric. type: string @@ -1293,22 +697,52 @@ components: description: The type of indicator. type: string example: sli.metric.custom - time_window_calendar_aligned: - title: Calendar aligned + time_window: + title: Time window required: - duration - - isCalendar - description: Defines properties for calendar aligned time window + - type + description: Defines properties for the SLO time window type: object properties: duration: - description: the duration formatted as {duration}{unit}, accept '1w' (weekly calendar) or '1M' (monthly calendar) only + description: 'the duration formatted as {duration}{unit}. Accepted values for rolling: 7d, 30d, 90d. Accepted values for calendar aligned: 1w (weekly) or 1M (monthly)' type: string - example: 1M - isCalendar: - description: Indicates a calendar aligned time window - type: boolean - example: true + example: 30d + type: + description: Indicates weither the time window is a rolling or a calendar aligned time window. + type: string + example: rolling + enum: + - rolling + - calendarAligned + budgeting_method: + title: Budgeting method + type: string + description: The budgeting method to use when computing the rollup data. + enum: + - occurrences + - timeslices + example: occurrences + objective: + title: Objective + required: + - target + description: Defines properties for the SLO objective + type: object + properties: + target: + description: the target objective between 0 and 1 excluded + type: number + example: 0.99 + timeslicesTarget: + description: the target objective for each slice when using a timeslices budgeting method + type: number + example: 0.995 + timeslicesWindow: + description: the duration of each slice when using a timeslices budgeting method, as {duraton}{unit} + type: string + example: 5m settings: title: Settings description: Defines properties for SLO settings. @@ -1322,6 +756,44 @@ components: description: Configure how often the transform runs, default 1m type: string example: 5m + error_budget: + title: Error budget + type: object + properties: + initial: + type: number + description: The initial error budget, as 1 - objective + example: 0.02 + consumed: + type: number + description: The error budget consummed, as a percentage of the initial value. + example: 0.8 + remaining: + type: number + description: The error budget remaining, as a percentage of the initial value. + example: 0.2 + isEstimated: + type: boolean + description: Only for SLO defined with occurrences budgeting method and calendar aligned time window. + example: true + summary: + title: Summary + type: object + description: The SLO computed data + properties: + status: + type: string + enum: + - NO_DATA + - HEALTHY + - DEGRADING + - VIOLATED + example: HEALTHY + sliValue: + type: number + example: 0.9836 + errorBudget: + $ref: '#/components/schemas/error_budget' slo_response: title: SLO response type: object @@ -1345,9 +817,7 @@ components: - $ref: '#/components/schemas/indicator_properties_apm_latency' - $ref: '#/components/schemas/indicator_properties_custom_metric' timeWindow: - oneOf: - - $ref: '#/components/schemas/time_window_rolling' - - $ref: '#/components/schemas/time_window_calendar_aligned' + $ref: '#/components/schemas/time_window' budgetingMethod: $ref: '#/components/schemas/budgeting_method' objective: @@ -1391,6 +861,74 @@ components: type: array items: $ref: '#/components/schemas/slo_response' + 400_response: + title: Bad request + type: object + required: + - statusCode + - error + - message + properties: + statusCode: + type: number + example: 400 + error: + type: string + example: Bad Request + message: + type: string + example: 'Invalid value ''foo'' supplied to: [...]' + 401_response: + title: Unauthorized + type: object + required: + - statusCode + - error + - message + properties: + statusCode: + type: number + example: 401 + error: + type: string + example: Unauthorized + message: + type: string + example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + 403_response: + title: Unauthorized + type: object + required: + - statusCode + - error + - message + properties: + statusCode: + type: number + example: 403 + error: + type: string + example: Unauthorized + message: + type: string + example: "[security_exception\n\tRoot causes:\n\t\tsecurity_exception: unable to authenticate user [elastics] for REST request [/_security/_authenticate]]: unable to authenticate user [elastics] for REST request [/_security/_authenticate]" + 404_response: + title: Not found + type: object + required: + - statusCode + - error + - message + properties: + statusCode: + type: number + example: 404 + error: + type: string + example: Not Found + message: + type: string + example: SLO [3749f390-03a3-11ee-8139-c7ff60a1692d] not found create_slo_request: title: Create SLO request description: | @@ -1421,9 +959,7 @@ components: - $ref: '#/components/schemas/indicator_properties_apm_latency' - $ref: '#/components/schemas/indicator_properties_custom_metric' timeWindow: - oneOf: - - $ref: '#/components/schemas/time_window_rolling' - - $ref: '#/components/schemas/time_window_calendar_aligned' + $ref: '#/components/schemas/time_window' budgetingMethod: $ref: '#/components/schemas/budgeting_method' objective: @@ -1439,6 +975,23 @@ components: id: type: string example: 8853df00-ae2e-11ed-90af-09bb6422b258 + 409_response: + title: Conflict + type: object + required: + - statusCode + - error + - message + properties: + statusCode: + type: number + example: 409 + error: + type: string + example: Conflict + message: + type: string + example: SLO [d077e940-1515-11ee-9c50-9d096392f520] already exists update_slo_request: title: Update SLO request description: | @@ -1458,9 +1011,7 @@ components: - $ref: '#/components/schemas/indicator_properties_apm_latency' - $ref: '#/components/schemas/indicator_properties_custom_metric' timeWindow: - oneOf: - - $ref: '#/components/schemas/time_window_rolling' - - $ref: '#/components/schemas/time_window_calendar_aligned' + $ref: '#/components/schemas/time_window' budgetingMethod: $ref: '#/components/schemas/budgeting_method' objective: @@ -1503,3 +1054,6 @@ components: example: 0.9836 errorBudget: $ref: '#/components/schemas/error_budget' +security: + - basicAuth: [] + - apiKeyAuth: [] diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/base_composite_slo_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/base_composite_slo_response.yaml index 08c5b7c7eba6e..8fce7e38f46de 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/base_composite_slo_response.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/base_composite_slo_response.yaml @@ -10,16 +10,16 @@ properties: type: string example: My Service SLO timeWindow: - $ref: 'time_window_rolling.yaml' + $ref: "time_window.yaml" budgetingMethod: - $ref: 'budgeting_method.yaml' + $ref: "budgeting_method.yaml" compositeMethod: - $ref: 'composite_method.yaml' + $ref: "composite_method.yaml" objective: - $ref: 'objective.yaml' + $ref: "objective.yaml" sources: oneOf: - - $ref: 'weighted_composite_sources.yaml' + - $ref: "weighted_composite_sources.yaml" createdAt: description: The creation date type: string diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/composite_slo_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/composite_slo_response.yaml index 305377500a932..e4c66379ef554 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/composite_slo_response.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/composite_slo_response.yaml @@ -10,18 +10,18 @@ properties: type: string example: My Service SLO timeWindow: - $ref: 'time_window_rolling.yaml' + $ref: "time_window.yaml" budgetingMethod: - $ref: 'budgeting_method.yaml' + $ref: "budgeting_method.yaml" compositeMethod: - $ref: 'composite_method.yaml' + $ref: "composite_method.yaml" objective: - $ref: 'objective.yaml' + $ref: "objective.yaml" sources: oneOf: - - $ref: 'weighted_composite_sources.yaml' + - $ref: "weighted_composite_sources.yaml" summary: - $ref: 'summary.yaml' + $ref: "summary.yaml" createdAt: description: The creation date type: string diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_composite_slo_request.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_composite_slo_request.yaml index 3db2a3ff738fc..46a801c75bba2 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_composite_slo_request.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_composite_slo_request.yaml @@ -18,14 +18,13 @@ properties: description: A name for the composite SLO. type: string timeWindow: - $ref: 'time_window_rolling.yaml' + $ref: "time_window.yaml" budgetingMethod: - $ref: 'budgeting_method.yaml' + $ref: "budgeting_method.yaml" compositeMethod: - $ref: 'composite_method.yaml' + $ref: "composite_method.yaml" objective: - $ref: 'objective.yaml' + $ref: "objective.yaml" sources: oneOf: - - $ref: 'weighted_composite_sources.yaml' - + - $ref: "weighted_composite_sources.yaml" diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_slo_request.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_slo_request.yaml index b9bf929611fc8..86394ff6f210c 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_slo_request.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_slo_request.yaml @@ -22,17 +22,15 @@ properties: type: string indicator: oneOf: - - $ref: 'indicator_properties_custom_kql.yaml' - - $ref: 'indicator_properties_apm_availability.yaml' - - $ref: 'indicator_properties_apm_latency.yaml' - - $ref: 'indicator_properties_custom_metric.yaml' + - $ref: "indicator_properties_custom_kql.yaml" + - $ref: "indicator_properties_apm_availability.yaml" + - $ref: "indicator_properties_apm_latency.yaml" + - $ref: "indicator_properties_custom_metric.yaml" timeWindow: - oneOf: - - $ref: 'time_window_rolling.yaml' - - $ref: 'time_window_calendar_aligned.yaml' + $ref: "time_window.yaml" budgetingMethod: - $ref: 'budgeting_method.yaml' + $ref: "budgeting_method.yaml" objective: - $ref: 'objective.yaml' + $ref: "objective.yaml" settings: - $ref: 'settings.yaml' + $ref: "settings.yaml" diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/indicator_properties_custom_metric.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/indicator_properties_custom_metric.yaml index 6746bf400e8d0..d97dc32fe0d11 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/indicator_properties_custom_metric.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/indicator_properties_custom_metric.yaml @@ -50,7 +50,7 @@ properties: description: The name of the metric. Only valid options are A-Z type: string example: A - pattern: '^[A-Z]$' + pattern: "^[A-Z]$" aggregation: description: The aggregation type of the metric. Only valid option is "sum" type: string @@ -63,7 +63,7 @@ properties: filter: description: The filter to apply to the metric. type: string - example: processor.outcome: "success" + example: 'processor.outcome: "success"' equation: description: The equation to calculate the "good" metric. type: string @@ -90,7 +90,7 @@ properties: description: The name of the metric. Only valid options are A-Z type: string example: A - pattern: '^[A-Z]$' + pattern: "^[A-Z]$" aggregation: description: The aggregation type of the metric. Only valid option is "sum" type: string @@ -103,7 +103,7 @@ properties: filter: description: The filter to apply to the metric. type: string - example: processor.outcome: * + example: "processor.outcome: *" equation: description: The equation to calculate the "total" metric. type: string diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml index 93e762ec3e6cf..afe03d12d676f 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml @@ -15,26 +15,24 @@ properties: example: My SLO description indicator: oneOf: - - $ref: 'indicator_properties_custom_kql.yaml' - - $ref: 'indicator_properties_apm_availability.yaml' - - $ref: 'indicator_properties_apm_latency.yaml' - - $ref: 'indicator_properties_custom_metric.yaml' + - $ref: "indicator_properties_custom_kql.yaml" + - $ref: "indicator_properties_apm_availability.yaml" + - $ref: "indicator_properties_apm_latency.yaml" + - $ref: "indicator_properties_custom_metric.yaml" timeWindow: - oneOf: - - $ref: 'time_window_rolling.yaml' - - $ref: 'time_window_calendar_aligned.yaml' + $ref: "time_window.yaml" budgetingMethod: - $ref: 'budgeting_method.yaml' + $ref: "budgeting_method.yaml" objective: - $ref: 'objective.yaml' + $ref: "objective.yaml" settings: - $ref: 'settings.yaml' + $ref: "settings.yaml" revision: description: The SLO revision type: number example: 2 summary: - $ref: 'summary.yaml' + $ref: "summary.yaml" enabled: description: Indicate if the SLO is enabled type: boolean diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window.yaml new file mode 100644 index 0000000000000..39ee742bcc07f --- /dev/null +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window.yaml @@ -0,0 +1,16 @@ +title: Time window +required: + - duration + - type +description: Defines properties for the SLO time window +type: object +properties: + duration: + description: "the duration formatted as {duration}{unit}. Accepted values for rolling: 7d, 30d, 90d. Accepted values for calendar aligned: 1w (weekly) or 1M (monthly)" + type: string + example: 30d + type: + description: Indicates weither the time window is a rolling or a calendar aligned time window. + type: string + example: "rolling" + enum: ["rolling", "calendarAligned"] diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window_calendar_aligned.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window_calendar_aligned.yaml deleted file mode 100644 index 7b914e114b268..0000000000000 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window_calendar_aligned.yaml +++ /dev/null @@ -1,15 +0,0 @@ -title: Calendar aligned -required: - - duration - - isCalendar -description: Defines properties for calendar aligned time window -type: object -properties: - duration: - description: the duration formatted as {duration}{unit}, accept '1w' (weekly calendar) or '1M' (monthly calendar) only - type: string - example: 1M - isCalendar: - description: Indicates a calendar aligned time window - type: boolean - example: true \ No newline at end of file diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window_rolling.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window_rolling.yaml deleted file mode 100644 index bf949153ee3f9..0000000000000 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/time_window_rolling.yaml +++ /dev/null @@ -1,15 +0,0 @@ -title: Rolling -required: - - duration - - isRolling -description: Defines properties for rolling time window -type: object -properties: - duration: - description: the duration formatted as {duration}{unit} - type: string - example: 28d - isRolling: - description: Indicates a rolling time window - type: boolean - example: true diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_composite_slo_request.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_composite_slo_request.yaml index 2095ca6a1d0ea..6368b62badf6e 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_composite_slo_request.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_composite_slo_request.yaml @@ -11,14 +11,13 @@ properties: description: A name for the composite SLO. type: string timeWindow: - $ref: 'time_window_rolling.yaml' + $ref: "time_window.yaml" budgetingMethod: - $ref: 'budgeting_method.yaml' + $ref: "budgeting_method.yaml" compositeMethod: - $ref: 'composite_method.yaml' + $ref: "composite_method.yaml" objective: - $ref: 'objective.yaml' + $ref: "objective.yaml" sources: oneOf: - - $ref: 'weighted_composite_sources.yaml' - + - $ref: "weighted_composite_sources.yaml" diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_slo_request.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_slo_request.yaml index aae12b175d782..0587ddf0abb2b 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_slo_request.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_slo_request.yaml @@ -12,17 +12,15 @@ properties: type: string indicator: oneOf: - - $ref: 'indicator_properties_custom_kql.yaml' - - $ref: 'indicator_properties_apm_availability.yaml' - - $ref: 'indicator_properties_apm_latency.yaml' - - $ref: 'indicator_properties_custom_metric.yaml' + - $ref: "indicator_properties_custom_kql.yaml" + - $ref: "indicator_properties_apm_availability.yaml" + - $ref: "indicator_properties_apm_latency.yaml" + - $ref: "indicator_properties_custom_metric.yaml" timeWindow: - oneOf: - - $ref: 'time_window_rolling.yaml' - - $ref: 'time_window_calendar_aligned.yaml' + $ref: "time_window.yaml" budgetingMethod: - $ref: 'budgeting_method.yaml' + $ref: "budgeting_method.yaml" objective: - $ref: 'objective.yaml' + $ref: "objective.yaml" settings: - $ref: 'settings.yaml' + $ref: "settings.yaml" diff --git a/x-pack/plugins/observability/docs/openapi/slo/entrypoint.yaml b/x-pack/plugins/observability/docs/openapi/slo/entrypoint.yaml index 94f6416103ade..44f16ed4585e0 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/entrypoint.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/entrypoint.yaml @@ -2,7 +2,7 @@ openapi: 3.0.1 info: title: SLOs description: OpenAPI schema for SLOs endpoints - version: '1.0' + version: "1.0" contact: name: Actionable Observability Team license: @@ -14,23 +14,23 @@ tags: - name: composite slo description: Composite SLO APIs enable you to define, manage and track a group of SLOs. servers: - - url: 'http://localhost:5601' + - url: "http://localhost:5601" description: local paths: - '/s/{spaceId}/api/observability/composite_slos': - $ref: 'paths/s@{spaceid}@api@composite_slos.yaml' - '/s/{spaceId}/api/observability/composite_slos/{compositeSloId}': - $ref: 'paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml' - '/s/{spaceId}/api/observability/slos': - $ref: 'paths/s@{spaceid}@api@slos.yaml' - '/s/{spaceId}/api/observability/slos/{sloId}': - $ref: 'paths/s@{spaceid}@api@slos@{sloid}.yaml' - '/s/{spaceId}/api/observability/slos/{sloId}/enable': - $ref: 'paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml' - '/s/{spaceId}/api/observability/slos/{sloId}/disable': - $ref: 'paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml' - '/s/{spaceId}/internal/observability/slos/_historical_summary': - $ref: 'paths/s@{spaceid}@api@slos@_historical_summary.yaml' + #'/s/{spaceId}/api/observability/composite_slos': + # $ref: 'paths/s@{spaceid}@api@composite_slos.yaml' + #'/s/{spaceId}/api/observability/composite_slos/{compositeSloId}': + # $ref: 'paths/s@{spaceid}@api@composite_slos@{compositesloid}.yaml' + "/s/{spaceId}/api/observability/slos": + $ref: "paths/s@{spaceid}@api@slos.yaml" + "/s/{spaceId}/api/observability/slos/{sloId}": + $ref: "paths/s@{spaceid}@api@slos@{sloid}.yaml" + "/s/{spaceId}/api/observability/slos/{sloId}/enable": + $ref: "paths/s@{spaceid}@api@slos@{sloid}@{enable}.yaml" + "/s/{spaceId}/api/observability/slos/{sloId}/disable": + $ref: "paths/s@{spaceid}@api@slos@{sloid}@{disable}.yaml" + "/s/{spaceId}/internal/observability/slos/_historical_summary": + $ref: "paths/s@{spaceid}@api@slos@_historical_summary.yaml" components: securitySchemes: basicAuth: From b83f47560fd48dfe6d07268e420efac861223242 Mon Sep 17 00:00:00 2001 From: Alexi Doak <109488926+doakalexi@users.noreply.github.com> Date: Tue, 11 Jul 2023 12:31:30 -0400 Subject: [PATCH 29/97] [Response Ops][Alerting] Allow runtime fields to be selected for Elasticsearch query rule type group by or aggregate over options (#160319) Resolves https://github.com/elastic/kibana/issues/157258 ## Summary Gets the runtime_mappings from the es query, and includes them in the query to retrieve the fields. Also gets runtime mappings from data views. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### To verify - Create a new Es Query rule using DSL - Include runtime mappings in your query and verify that the runtime fields are listed in the group by or aggregate over options below the query - Create a dataview and include runtime fields - Create a new Es Query rule using KQL - Verify that the runtime fields are listed in the group by or aggregate over options below the query --- .../expression/es_query_expression.tsx | 23 ++++- .../public/rule_types/es_query/util.test.ts | 85 ++++++++++++++++++- .../public/rule_types/es_query/util.ts | 32 ++++++- .../triggers_actions_ui/common/index.ts | 1 + .../common/normalized_field_types.ts | 18 ++++ .../public/common/index.ts | 1 + .../server/data/routes/fields.ts | 15 +--- 7 files changed, 156 insertions(+), 19 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/es_query_expression.tsx b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/es_query_expression.tsx index bf0af46912c62..f3a0c0175b300 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/es_query_expression.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/expression/es_query_expression.tsx @@ -6,6 +6,7 @@ */ import React, { useState, Fragment, useEffect, useCallback } from 'react'; +import { get, sortBy } from 'lodash'; import { lastValueFrom } from 'rxjs'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -32,7 +33,7 @@ import { EsQueryRuleParams, EsQueryRuleMetaData, SearchType } from '../types'; import { IndexSelectPopover } from '../../components/index_select_popover'; import { DEFAULT_VALUES } from '../constants'; import { RuleCommonExpressions } from '../rule_common_expressions'; -import { useTriggerUiActionServices } from '../util'; +import { convertRawRuntimeFieldtoFieldOption, useTriggerUiActionServices } from '../util'; const { useXJsonMode } = XJson; @@ -89,6 +90,8 @@ export const EsQueryExpression: React.FC< const { http, docLinks } = services; const [esFields, setEsFields] = useState([]); + const [runtimeFields, setRuntimeFields] = useState([]); + const [combinedFields, setCombinedFields] = useState([]); const { convertToJson, setXJson, xJson } = useXJsonMode(DEFAULT_VALUES.QUERY); const setDefaultExpressionValues = async () => { @@ -108,6 +111,21 @@ export const EsQueryExpression: React.FC< const refreshEsFields = async (indices: string[]) => { const currentEsFields = await getFields(http, indices); setEsFields(currentEsFields); + setCombinedFields(sortBy(currentEsFields.concat(runtimeFields), 'name')); + }; + + const getRuntimeFields = () => { + let runtimeMappings; + try { + runtimeMappings = get(JSON.parse(xJson), 'runtime_mappings'); + } catch (e) { + // ignore error + } + if (runtimeMappings) { + const currentRuntimeFields = convertRawRuntimeFieldtoFieldOption(runtimeMappings); + setRuntimeFields(currentRuntimeFields); + setCombinedFields(sortBy(esFields.concat(currentRuntimeFields), 'name')); + } }; const onTestQuery = useCallback(async () => { @@ -252,6 +270,7 @@ export const EsQueryExpression: React.FC< onChange={(xjson: string) => { setXJson(xjson); setParam('esQuery', convertToJson(xjson)); + getRuntimeFields(); }} options={{ ariaLabel: i18n.translate('xpack.stackAlerts.esQuery.ui.queryEditor', { @@ -276,7 +295,7 @@ export const EsQueryExpression: React.FC< timeWindowSize={timeWindowSize} timeWindowUnit={timeWindowUnit} size={size} - esFields={esFields} + esFields={combinedFields} aggType={aggType} aggField={aggField} groupBy={groupBy} diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/util.test.ts b/x-pack/plugins/stack_alerts/public/rule_types/es_query/util.test.ts index 355c3e19516d6..f2d6e6abe250f 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/util.test.ts +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/util.test.ts @@ -5,12 +5,30 @@ * 2.0. */ -import { convertFieldSpecToFieldOption } from './util'; +import { convertFieldSpecToFieldOption, convertRawRuntimeFieldtoFieldOption } from './util'; -describe('convertFieldSpecToFieldOption', () => { +describe('Es Query utils', () => { test('should correctly convert FieldSpec to FieldOption', () => { expect( convertFieldSpecToFieldOption([ + { + count: 0, + name: 'day_of_week', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: false, + shortDotsEnable: false, + runtimeField: { + type: 'keyword', + script: { + source: + "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", + }, + }, + }, { count: 0, name: '@timestamp', @@ -85,6 +103,13 @@ describe('convertFieldSpecToFieldOption', () => { }, ]) ).toEqual([ + { + name: 'day_of_week', + type: 'keyword', + normalizedType: 'keyword', + aggregatable: true, + searchable: true, + }, { name: '@timestamp', type: 'date', @@ -122,4 +147,60 @@ describe('convertFieldSpecToFieldOption', () => { }, ]); }); + + test('should correctly convert raw runtime field to FieldOption', () => { + expect( + convertRawRuntimeFieldtoFieldOption({ + day_of_week: { + type: 'keyword', + script: { + source: + "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", + }, + }, + location: { + type: 'lookup', + target_index: 'ip_location', + input_field: 'host', + target_field: 'ip', + fetch_fields: ['country', 'city'], + }, + }) + ).toEqual([ + { + name: 'day_of_week', + type: 'keyword', + normalizedType: 'keyword', + aggregatable: true, + searchable: true, + }, + { + name: 'location', + type: 'lookup', + normalizedType: 'lookup', + aggregatable: false, + searchable: false, + }, + ]); + }); + + test('should return an empty array if raw runtime fields are malformed JSON', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const rawFields: any = null; + expect(convertRawRuntimeFieldtoFieldOption(rawFields)).toEqual([]); + }); + + test('should not return FieldOption if raw runtime fields do not include the type', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const rawFields: any = { + day_of_week: { + test: 'keyword', + script: { + source: + "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", + }, + }, + }; + expect(convertRawRuntimeFieldtoFieldOption(rawFields)).toEqual([]); + }); }); diff --git a/x-pack/plugins/stack_alerts/public/rule_types/es_query/util.ts b/x-pack/plugins/stack_alerts/public/rule_types/es_query/util.ts index c4ec66a21c4e8..5568924e845e4 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/es_query/util.ts +++ b/x-pack/plugins/stack_alerts/public/rule_types/es_query/util.ts @@ -7,7 +7,8 @@ import { FieldSpec } from '@kbn/data-views-plugin/common'; import { useKibana } from '@kbn/triggers-actions-ui-plugin/public'; -import { FieldOption } from '@kbn/triggers-actions-ui-plugin/public/common'; +import { FieldOption, NORMALIZED_FIELD_TYPES } from '@kbn/triggers-actions-ui-plugin/public/common'; +import { estypes } from '@elastic/elasticsearch'; import { EsQueryRuleParams, SearchType } from './types'; export const isSearchSourceRule = ( @@ -18,7 +19,7 @@ export const isSearchSourceRule = ( export const convertFieldSpecToFieldOption = (fieldSpec: FieldSpec[]): FieldOption[] => { return (fieldSpec ?? []) - .filter((spec: FieldSpec) => spec.isMapped) + .filter((spec: FieldSpec) => spec.isMapped || spec.runtimeField) .map((spec: FieldSpec) => { const converted = { name: spec.name, @@ -41,4 +42,31 @@ export const convertFieldSpecToFieldOption = (fieldSpec: FieldSpec[]): FieldOpti }); }; +export const convertRawRuntimeFieldtoFieldOption = ( + rawFields: Record +): FieldOption[] => { + const result: FieldOption[] = []; + + // verifying that the raw fields are an object + let keys; + try { + keys = Object.keys(rawFields); + } catch (e) { + return result; + } + + for (const name of keys) { + const rawField = rawFields[name]; + const type = rawField.type; + + const normalizedType = NORMALIZED_FIELD_TYPES[type] || type; + const isAggregatableAndSearchable = type !== 'lookup'; + const aggregatable = isAggregatableAndSearchable; + const searchable = isAggregatableAndSearchable; + + if (type) result.push({ name, type, normalizedType, aggregatable, searchable }); + } + return result; +}; + export const useTriggerUiActionServices = () => useKibana().services; diff --git a/x-pack/plugins/triggers_actions_ui/common/index.ts b/x-pack/plugins/triggers_actions_ui/common/index.ts index 1675dee6129d9..142f6e8ac9c81 100644 --- a/x-pack/plugins/triggers_actions_ui/common/index.ts +++ b/x-pack/plugins/triggers_actions_ui/common/index.ts @@ -12,3 +12,4 @@ export * from './data'; export const BASE_TRIGGERS_ACTIONS_UI_API_PATH = '/internal/triggers_actions_ui'; export * from './parse_interval'; export * from './experimental_features'; +export * from './normalized_field_types'; diff --git a/x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts b/x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts new file mode 100644 index 0000000000000..7f69685111f4f --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const NORMALIZED_FIELD_TYPES: Record = { + long: 'number', + integer: 'number', + short: 'number', + byte: 'number', + double: 'number', + float: 'number', + half_float: 'number', + scaled_float: 'number', + unsigned_long: 'number', +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/common/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/index.ts index 4cf4f8c855d4e..f9b3cc7c8654c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/index.ts @@ -39,5 +39,6 @@ export { isCountAggregation, isGroupAggregation, parseAggregationResults, + NORMALIZED_FIELD_TYPES, } from '../../common'; export type { ParsedAggregationGroup } from '../../common'; diff --git a/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts b/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts index e2c4302afe352..bf45b702a84ec 100644 --- a/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts +++ b/x-pack/plugins/triggers_actions_ui/server/data/routes/fields.ts @@ -15,6 +15,7 @@ import { ElasticsearchClient, } from '@kbn/core/server'; import { Logger } from '@kbn/core/server'; +import { NORMALIZED_FIELD_TYPES } from '../../../common'; const bodySchema = schema.object({ indexPatterns: schema.arrayOf(schema.string()), @@ -118,7 +119,7 @@ function getFieldsFromRawFields(rawFields: RawFields): Field[] { if (!type || type.startsWith('_')) continue; if (!values) continue; - const normalizedType = normalizedFieldTypes[type] || type; + const normalizedType = NORMALIZED_FIELD_TYPES[type] || type; const aggregatable = values.aggregatable; const searchable = values.searchable; @@ -128,15 +129,3 @@ function getFieldsFromRawFields(rawFields: RawFields): Field[] { result.sort((a, b) => a.name.localeCompare(b.name)); return result; } - -const normalizedFieldTypes: Record = { - long: 'number', - integer: 'number', - short: 'number', - byte: 'number', - double: 'number', - float: 'number', - half_float: 'number', - scaled_float: 'number', - unsigned_long: 'number', -}; From f4e9cd15d5318e6a3b3432d2e3039bae4a229250 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 11 Jul 2023 12:35:49 -0400 Subject: [PATCH 30/97] skip failing test suite (#157711) --- x-pack/test/functional/apps/infra/home_page.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/infra/home_page.ts b/x-pack/test/functional/apps/infra/home_page.ts index 88d7538043e32..842f32efc9933 100644 --- a/x-pack/test/functional/apps/infra/home_page.ts +++ b/x-pack/test/functional/apps/infra/home_page.ts @@ -21,7 +21,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const kibanaServer = getService('kibanaServer'); const testSubjects = getService('testSubjects'); - describe('Home page', function () { + // Failing: See https://github.com/elastic/kibana/issues/157711 + describe.skip('Home page', function () { this.tags('includeFirefox'); before(async () => { await kibanaServer.savedObjects.cleanStandardList(); From dd292b70b7fc121dcef4fad84b979d730b6c6f6e Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau Date: Tue, 11 Jul 2023 13:25:20 -0400 Subject: [PATCH 31/97] [RAM] Remove allow slack channels (#161674) ## Summary Remove allow slack channels feature for 8.9 until we have a better way to deal with channels ### Checklist - [X] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../common/slack_api/schema.ts | 4 +- .../slack_api/slack_connectors.test.tsx | 78 +------------ .../slack_api/slack_connectors.tsx | 62 +--------- .../connector_types/slack_api/index.test.ts | 14 --- .../server/connector_types/slack_api/index.ts | 1 - .../connector_types/slack_api/service.test.ts | 45 -------- .../connector_types/slack_api/service.ts | 33 +----- .../plugins/stack_connectors/server/plugin.ts | 11 +- .../server/routes/get_slack_api_channels.ts | 109 ------------------ .../stack_connectors/server/routes/index.ts | 1 - 10 files changed, 9 insertions(+), 349 deletions(-) delete mode 100644 x-pack/plugins/stack_connectors/server/routes/get_slack_api_channels.ts diff --git a/x-pack/plugins/stack_connectors/common/slack_api/schema.ts b/x-pack/plugins/stack_connectors/common/slack_api/schema.ts index 3a96528ba2801..4f121fd92389a 100644 --- a/x-pack/plugins/stack_connectors/common/slack_api/schema.ts +++ b/x-pack/plugins/stack_connectors/common/slack_api/schema.ts @@ -11,9 +11,7 @@ export const SlackApiSecretsSchema = schema.object({ token: schema.string({ minLength: 1 }), }); -export const SlackApiConfigSchema = schema.object({ - allowedChannels: schema.maybe(schema.arrayOf(schema.string())), -}); +export const SlackApiConfigSchema = schema.object({}, { defaultValue: {} }); export const GetChannelsParamsSchema = schema.object({ subAction: schema.literal('getChannels'), diff --git a/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_connectors.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_connectors.test.tsx index 8346e4b07c697..8c255bce003fe 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_connectors.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_connectors.test.tsx @@ -48,16 +48,14 @@ describe('SlackActionFields renders', () => { secrets: { token: 'some token', }, - config: { - allowedChannels: ['foo', 'bar'], - }, + config: {}, id: 'test', actionTypeId: '.slack', name: 'slack', isDeprecated: false, }; - const { container } = render( + render( {}} /> @@ -65,17 +63,6 @@ describe('SlackActionFields renders', () => { expect(screen.getByTestId('secrets.token-input')).toBeInTheDocument(); expect(screen.getByTestId('secrets.token-input')).toHaveValue('some token'); - expect(screen.getByTestId('config.allowedChannels-input')).toBeInTheDocument(); - const allowedChannels: string[] = []; - container - .querySelectorAll('[data-test-subj="config.allowedChannels-input"] .euiBadge') - .forEach((node) => { - const channel = node.getAttribute('title'); - if (channel) { - allowedChannels.push(channel); - } - }); - expect(allowedChannels).toEqual(['foo', 'bar']); }); it('connector validation succeeds when connector config is valid for Web API type', async () => { @@ -105,9 +92,6 @@ describe('SlackActionFields renders', () => { secrets: { token: 'some token', }, - config: { - allowedChannels: [], - }, id: 'test', actionTypeId: '.slack', name: 'slack', @@ -116,62 +100,4 @@ describe('SlackActionFields renders', () => { isValid: true, }); }); - - it('Allowed Channels combobox should be disable when there is NO token', async () => { - const actionConnector = { - secrets: { - token: '', - }, - config: { - allowedChannels: ['foo', 'bar'], - }, - id: 'test', - actionTypeId: '.slack', - name: 'slack', - isDeprecated: false, - }; - - const { container } = render( - - {}} /> - - ); - expect( - container.querySelector( - '[data-test-subj="config.allowedChannels-input"].euiComboBox-isDisabled' - ) - ).toBeInTheDocument(); - }); - - it('Allowed Channels combobox should NOT be disable when there is token', async () => { - const actionConnector = { - secrets: { - token: 'qwertyuiopasdfghjklzxcvbnm', - }, - config: { - allowedChannels: ['foo', 'bar'], - }, - id: 'test', - actionTypeId: '.slack', - name: 'slack', - isDeprecated: false, - }; - - (useFetchChannels as jest.Mock).mockImplementation(() => ({ - channels: [{ label: 'foo' }, { label: 'bar' }, { label: 'hello' }, { label: 'world' }], - isLoading: false, - })); - - const { container } = render( - - {}} /> - - ); - - expect( - container.querySelector( - '[data-test-subj="config.allowedChannels-input"].euiComboBox-isDisabled' - ) - ).not.toBeInTheDocument(); - }); }); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_connectors.tsx b/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_connectors.tsx index 2caf8bff0b611..71a262954d2d1 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_connectors.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/slack_api/slack_connectors.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useEffect, useMemo, useState } from 'react'; +import React from 'react'; import { ActionConnectorFieldsProps, ConfigFieldSchema, @@ -13,18 +13,12 @@ import { SimpleConnectorForm, useKibana, } from '@kbn/triggers-actions-ui-plugin/public'; -import { EuiComboBoxOptionOption, EuiLink } from '@elastic/eui'; +import { EuiLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { DocLinksStart } from '@kbn/core/public'; -import { useFormContext, useFormData } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; -import { debounce, isEmpty } from 'lodash'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import * as i18n from './translations'; -import { useFetchChannels } from './use_fetch_channels'; - -/** wait this many ms after the user completes typing before applying the filter input */ -const INPUT_TIMEOUT = 250; const getSecretsFormSchema = (docLinks: DocLinksStart): SecretsFieldSchema[] => [ { @@ -42,31 +36,6 @@ const getSecretsFormSchema = (docLinks: DocLinksStart): SecretsFieldSchema[] => }, ]; -const getConfigFormSchemaAfterSecrets = ( - options: EuiComboBoxOptionOption[], - isLoading: boolean, - isDisabled: boolean -): ConfigFieldSchema[] => [ - { - id: 'allowedChannels', - isRequired: false, - label: i18n.ALLOWED_CHANNELS, - helpText: ( - - ), - type: 'COMBO_BOX', - euiFieldProps: { - isDisabled, - isLoading, - noSuggestions: false, - options, - }, - }, -]; - const NO_SCHEMA: ConfigFieldSchema[] = []; export const SlackActionFieldsComponents: React.FC = ({ @@ -75,39 +44,12 @@ export const SlackActionFieldsComponents: React.FC = }) => { const { docLinks } = useKibana().services; - const form = useFormContext(); - const { setFieldValue } = form; - const [formData] = useFormData({ form }); - const [authToken, setAuthToken] = useState(''); - - const { channels, isLoading } = useFetchChannels({ authToken }); - const configFormSchemaAfterSecrets = useMemo( - () => getConfigFormSchemaAfterSecrets(channels, isLoading, channels.length === 0), - [channels, isLoading] - ); - - const debounceSetToken = debounce(setAuthToken, INPUT_TIMEOUT); - useEffect(() => { - if (formData.secrets && formData.secrets.token !== authToken) { - debounceSetToken(formData.secrets.token); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [formData.secrets]); - - useEffect(() => { - if (isEmpty(authToken) && channels.length > 0) { - setFieldValue('config.allowedChannels', []); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [authToken]); - return ( ); }; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.test.ts index 2b4022285dea8..c4922020cdce7 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.test.ts @@ -55,23 +55,9 @@ describe('validate config', () => { }).toThrowErrorMatchingInlineSnapshot( `"error validating action type config: [message]: definition for this key is missing"` ); - - expect(() => { - validateConfig(connectorType, { allowedChannels: 'foo' }, { configurationUtilities }); - }).toThrowErrorMatchingInlineSnapshot( - `"error validating action type config: [allowedChannels]: could not parse array value from json input"` - ); }); test('should validate when config are valid', () => { - expect(() => { - validateConfig( - connectorType, - { allowedChannels: ['foo', 'bar'] }, - { configurationUtilities } - ); - }).not.toThrow(); - expect(() => { validateConfig(connectorType, {}, { configurationUtilities }); }).not.toThrow(); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.ts index bc3128dc666b8..ffb952f457956 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/index.ts @@ -105,7 +105,6 @@ const slackApiExecutor = async ({ const externalService = createExternalService( { - config, secrets, }, logger, diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.test.ts index 2f22944ff6480..85df189c72d29 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.test.ts @@ -177,50 +177,5 @@ describe('Slack API service', () => { status: 'error', }); }); - - test('should NOT by pass allowed channels when present', async () => { - service = createExternalService( - { - secrets: { token: 'token' }, - config: { allowedChannels: ['foo', 'bar'] }, - }, - logger, - configurationUtilities - ); - - expect( - await service.postMessage({ channels: ['general', 'privat'], text: 'a message' }) - ).toEqual({ - actionId: SLACK_API_CONNECTOR_ID, - serviceMessage: - 'The channel "general,privat" is not included in the allowed channels list "foo,bar"', - message: 'error posting slack message', - status: 'error', - }); - }); - - test('should allowed channels to be persisted', async () => { - service = createExternalService( - { - secrets: { token: 'token' }, - config: { allowedChannels: ['foo', 'bar', 'general', 'privat'] }, - }, - logger, - configurationUtilities - ); - requestMock.mockImplementation(() => postMessageResponse); - - await service.postMessage({ channels: ['general', 'privat'], text: 'a message' }); - - expect(requestMock).toHaveBeenCalledTimes(1); - expect(requestMock).toHaveBeenNthCalledWith(1, { - axios, - logger, - configurationUtilities, - method: 'post', - url: 'chat.postMessage', - data: { channel: 'general', text: 'a message' }, - }); - }); }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts index a2b6ff8989880..2db25dc52f223 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts @@ -106,12 +106,11 @@ const buildSlackExecutorSuccessResponse = ({ }; export const createExternalService = ( - { config, secrets }: { config?: { allowedChannels?: string[] }; secrets: { token: string } }, + { secrets }: { secrets: { token: string } }, logger: Logger, configurationUtilities: ActionsConfigurationUtilities ): SlackApiService => { const { token } = secrets; - const { allowedChannels } = config || { allowedChannels: [] }; if (!token) { throw Error(`[Action][${SLACK_CONNECTOR_NAME}]: Wrong configuration.`); } @@ -170,23 +169,6 @@ export const createExternalService = ( } result.data.channels = channels; const responseData = result.data; - if ((allowedChannels ?? []).length > 0) { - const allowedChannelsList = channels.filter((channel: ChannelsResponse) => - allowedChannels?.includes(channel.name) - ); - allowedChannels?.forEach((ac) => { - if (!allowedChannelsList.find((c: ChannelsResponse) => c.name === ac)) { - allowedChannelsList.push({ - id: '-1', - name: ac, - is_channel: true, - is_archived: false, - is_private: false, - }); - } - }); - responseData.channels = allowedChannelsList; - } return buildSlackExecutorSuccessResponse({ slackApiResponseData: responseData, @@ -201,19 +183,6 @@ export const createExternalService = ( text, }: PostMessageSubActionParams): Promise> => { try { - if ( - allowedChannels && - allowedChannels.length > 0 && - !channels.every((c) => allowedChannels?.includes(c)) - ) { - return buildSlackExecutorErrorResponse({ - slackApiError: { - message: `The channel "${channels.join()}" is not included in the allowed channels list "${allowedChannels.join()}"`, - }, - logger, - }); - } - const result: AxiosResponse = await request({ axios: axiosInstance, method: 'post', diff --git a/x-pack/plugins/stack_connectors/server/plugin.ts b/x-pack/plugins/stack_connectors/server/plugin.ts index 3e76b9adbb083..ce1795b4eb7fb 100644 --- a/x-pack/plugins/stack_connectors/server/plugin.ts +++ b/x-pack/plugins/stack_connectors/server/plugin.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { PluginInitializerContext, Plugin, CoreSetup, Logger } from '@kbn/core/server'; +import { PluginInitializerContext, Plugin, CoreSetup } from '@kbn/core/server'; import { PluginSetupContract as ActionsPluginSetupContract } from '@kbn/actions-plugin/server'; import { registerConnectorTypes } from './connector_types'; -import { getSlackApiChannelsRoute, getWellKnownEmailServiceRoute } from './routes'; +import { getWellKnownEmailServiceRoute } from './routes'; export interface ConnectorsPluginsSetup { actions: ActionsPluginSetupContract; } @@ -18,18 +18,13 @@ export interface ConnectorsPluginsStart { } export class StackConnectorsPlugin implements Plugin { - private readonly logger: Logger; - - constructor(context: PluginInitializerContext) { - this.logger = context.logger.get(); - } + constructor(context: PluginInitializerContext) {} public setup(core: CoreSetup, plugins: ConnectorsPluginsSetup) { const router = core.http.createRouter(); const { actions } = plugins; getWellKnownEmailServiceRoute(router); - getSlackApiChannelsRoute(router, actions.getActionsConfigurationUtilities(), this.logger); registerConnectorTypes({ actions, diff --git a/x-pack/plugins/stack_connectors/server/routes/get_slack_api_channels.ts b/x-pack/plugins/stack_connectors/server/routes/get_slack_api_channels.ts deleted file mode 100644 index dac35c0503cbe..0000000000000 --- a/x-pack/plugins/stack_connectors/server/routes/get_slack_api_channels.ts +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { schema } from '@kbn/config-schema'; -import { - IRouter, - RequestHandlerContext, - KibanaRequest, - IKibanaResponse, - KibanaResponseFactory, - Logger, -} from '@kbn/core/server'; -import axios, { AxiosResponse } from 'axios'; -import { request } from '@kbn/actions-plugin/server/lib/axios_utils'; -import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config'; -import { INTERNAL_BASE_STACK_CONNECTORS_API_PATH } from '../../common'; -import { SLACK_URL } from '../../common/slack_api/constants'; -import { ChannelsResponse, GetChannelsResponse } from '../../common/slack_api/types'; - -const bodySchema = schema.object({ - authToken: schema.string(), -}); - -const RE_TRY = 5; -const LIMIT = 1000; - -export const getSlackApiChannelsRoute = ( - router: IRouter, - configurationUtilities: ActionsConfigurationUtilities, - logger: Logger -) => { - router.post( - { - path: `${INTERNAL_BASE_STACK_CONNECTORS_API_PATH}/_slack_api/channels`, - validate: { - body: bodySchema, - }, - }, - handler - ); - - async function handler( - ctx: RequestHandlerContext, - req: KibanaRequest, - res: KibanaResponseFactory - ): Promise { - const { authToken } = req.body; - - const axiosInstance = axios.create({ - baseURL: SLACK_URL, - headers: { - Authorization: `Bearer ${authToken}`, - 'Content-type': 'application/json; charset=UTF-8', - }, - }); - - const fetchChannels = (cursor: string = ''): Promise> => { - return request({ - axios: axiosInstance, - configurationUtilities, - logger, - method: 'get', - url: `conversations.list?exclude_archived=true&types=public_channel,private_channel&limit=${LIMIT}${ - cursor.length > 0 ? `&cursor=${cursor}` : '' - }`, - }); - }; - - let numberOfFetch = 0; - let cursor = ''; - const channels: ChannelsResponse[] = []; - let result: AxiosResponse = { - data: { ok: false, channels }, - status: 0, - statusText: '', - headers: {}, - config: {}, - }; - - while (numberOfFetch < RE_TRY) { - result = await fetchChannels(cursor); - if (result.data.ok && (result.data?.channels ?? []).length > 0) { - channels.push(...(result.data?.channels ?? [])); - } - if ( - result.data.ok && - result.data.response_metadata && - result.data.response_metadata.next_cursor && - result.data.response_metadata.next_cursor.length > 0 - ) { - numberOfFetch += 1; - cursor = result.data.response_metadata.next_cursor; - } else { - break; - } - } - - return res.ok({ - body: { - ...result.data, - channels, - }, - }); - } -}; diff --git a/x-pack/plugins/stack_connectors/server/routes/index.ts b/x-pack/plugins/stack_connectors/server/routes/index.ts index df48f18480252..2766b99679845 100644 --- a/x-pack/plugins/stack_connectors/server/routes/index.ts +++ b/x-pack/plugins/stack_connectors/server/routes/index.ts @@ -6,4 +6,3 @@ */ export { getWellKnownEmailServiceRoute } from './get_well_known_email_service'; -export { getSlackApiChannelsRoute } from './get_slack_api_channels'; From 4ce8b3f4ebb602030ad1a7dbbc999e5128ad3daa Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Tue, 11 Jul 2023 10:39:30 -0700 Subject: [PATCH 32/97] [DOCS] Edits FormatNumber examples for rule action variables (#161678) --- docs/user/alerting/action-variables.asciidoc | 44 ++++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/docs/user/alerting/action-variables.asciidoc b/docs/user/alerting/action-variables.asciidoc index b3a2854642029..5e26dd874f67e 100644 --- a/docs/user/alerting/action-variables.asciidoc +++ b/docs/user/alerting/action-variables.asciidoc @@ -116,14 +116,14 @@ For diagnostic or exploratory purposes, action variables whose values are object For situations where your rule response returns arrays of data, you can loop through the `context`: -[source] +[source,sh] -------------------------------------------------- {{#context}}{{.}}{{/context}} -------------------------------------------------- For example, looping through search result hits: -[source] +[source,sh] -------------------------------------------------- triggering data was: {{#context.hits}} - {{_source.message}} @@ -154,7 +154,7 @@ The following capabilities are available: Mustache lambdas provide additional rendering capabilities for Mustache templates. A Mustache lambda is formatted like a Mustache section. For example: -[source] +[source,sh] ---- {{#EvalMath}} round(context.value, 1) {{/EvalMath}} ---- @@ -169,7 +169,7 @@ The EvalMath lambda will evaluate the text passed to it as <` parameter is required; the `
,
"`; +exports[`ResetSessionPage renders as expected 1`] = `"ElasticMockedFonts

You do not have permission to access the requested page

Either go back to the previous page or log in as a different user.

"`; -exports[`ResetSessionPage renders as expected with custom page title 1`] = `"My Company NameMockedFonts

You do not have permission to access the requested page

Either go back to the previous page or log in as a different user.

"`; +exports[`ResetSessionPage renders as expected with custom page title 1`] = `"My Company NameMockedFonts

You do not have permission to access the requested page

Either go back to the previous page or log in as a different user.

"`; diff --git a/yarn.lock b/yarn.lock index 8fd75878053a0..ce26e20144928 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1552,10 +1552,10 @@ resolved "https://registry.yarnpkg.com/@elastic/eslint-plugin-eui/-/eslint-plugin-eui-0.0.2.tgz#56b9ef03984a05cc213772ae3713ea8ef47b0314" integrity sha512-IoxURM5zraoQ7C8f+mJb9HYSENiZGgRVcG4tLQxE61yHNNRDXtGDWTZh8N1KIHcsqN1CEPETjuzBXkJYF/fDiQ== -"@elastic/eui@83.0.0": - version "83.0.0" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-83.0.0.tgz#32d6a4516ff4bbc058cf604cf323536ce57748e7" - integrity sha512-xoGa/+WmqNV4+GwM7k9u610nAzL4MiWLns55qZdkftuN0zOwFjlnQS2bd+NJlNNXVB9PfeOIKfpvdB4iMIRsFA== +"@elastic/eui@83.1.0": + version "83.1.0" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-83.1.0.tgz#ed1e409306da2ed9171d334e0ed7e6622c499141" + integrity sha512-l6ERa836K/U9dccZ4xkyf2tmTO54DeElhGXmNdq02CATbXNQ3YGnoAn99+HvA82oXF3zCSpy+pg5tLx6Ag1zaw== dependencies: "@types/chroma-js" "^2.0.0" "@types/lodash" "^4.14.194" From 6673ffbf18f372ddf8569b8106532f05a45f2d88 Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Tue, 11 Jul 2023 14:52:45 -0600 Subject: [PATCH 43/97] [Security solution] Elastic Assistant adds beta label (#161682) --- .../impl/assistant/assistant_title/index.tsx | 90 +++++++++++++++++++ .../impl/assistant/index.tsx | 13 +-- .../impl/assistant/translations.ts | 21 +++++ .../impl/assistant_context/index.test.tsx | 4 + .../impl/assistant_context/index.tsx | 6 ++ .../mock/test_providers/test_providers.tsx | 4 + .../kbn-elastic-assistant/tsconfig.json | 1 + .../mock/test_providers/test_providers.tsx | 4 + .../security_solution/public/app/app.tsx | 3 + .../common/mock/mock_assistant_provider.tsx | 4 + 10 files changed, 140 insertions(+), 10 deletions(-) create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_title/index.tsx diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_title/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_title/index.tsx new file mode 100644 index 0000000000000..150eacd37a616 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_title/index.tsx @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FunctionComponent, useMemo, useState } from 'react'; +import { + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiLink, + EuiModalHeaderTitle, + EuiPopover, + EuiText, +} from '@elastic/eui'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; +import { FormattedMessage } from '@kbn/i18n-react'; +import * as i18n from '../translations'; + +export const AssistantTitle: FunctionComponent<{ + currentTitle: { title: string | JSX.Element; titleIcon: string }; + docLinks: Omit; +}> = ({ currentTitle, docLinks }) => { + const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = docLinks; + const url = `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/security-assistant.html`; + + const documentationLink = useMemo( + () => ( + + {i18n.DOCUMENTATION} + + ), + [url] + ); + + const content = useMemo( + () => ( + + ), + [documentationLink] + ); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const onButtonClick = () => setIsPopoverOpen((isOpen: boolean) => !isOpen); + const closePopover = () => setIsPopoverOpen(false); + return ( + + + + + + {currentTitle.title} + + + } + isOpen={isPopoverOpen} + closePopover={closePopover} + anchorPosition="upCenter" + > + +

{i18n.TOOLTIP_TITLE}

+

{content}

+
+
+
+
+
+ ); +}; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx index 99f9744e9a949..8e1af141ede65 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx @@ -17,11 +17,9 @@ import { EuiSwitchEvent, EuiSwitch, EuiCallOut, - EuiIcon, EuiModalFooter, EuiModalHeader, EuiModalBody, - EuiModalHeaderTitle, } from '@elastic/eui'; import { createPortal } from 'react-dom'; @@ -29,6 +27,7 @@ import { css } from '@emotion/react'; import { OpenAiProviderType } from '@kbn/stack-connectors-plugin/common/gen_ai/constants'; import { ActionConnectorProps } from '@kbn/triggers-actions-ui-plugin/public/types'; +import { AssistantTitle } from './assistant_title'; import { UpgradeButtons } from '../upgrade/upgrade_buttons'; import { getMessageFromRawResponse } from './helpers'; @@ -78,6 +77,7 @@ const AssistantComponent: React.FC = ({ conversations, defaultAllow, defaultAllowReplacement, + docLinks, getComments, http, promptContexts, @@ -452,14 +452,7 @@ const AssistantComponent: React.FC = ({ justifyContent={'spaceBetween'} > - - - - - - {currentTitle.title} - - + ( baseAllowReplacement={[]} defaultAllow={[]} defaultAllowReplacement={[]} + docLinks={{ + ELASTIC_WEBSITE_URL: 'https://www.elastic.co/', + DOC_LINK_VERSION: 'current', + }} getInitialConversations={mockGetInitialConversations} getComments={mockGetComments} http={mockHttp} diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx index c332e2687646e..7a3c2e0dde870 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx @@ -12,6 +12,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { ActionTypeRegistryContract } from '@kbn/triggers-actions-ui-plugin/public'; import { useLocalStorage } from 'react-use'; +import type { DocLinksStart } from '@kbn/core-doc-links-browser'; import { updatePromptContexts } from './helpers'; import type { PromptContext, @@ -52,6 +53,7 @@ interface AssistantProviderProps { basePromptContexts?: PromptContextTemplate[]; baseQuickPrompts?: QuickPrompt[]; baseSystemPrompts?: Prompt[]; + docLinks: Omit; children: React.ReactNode; getComments: ({ currentConversation, @@ -78,6 +80,7 @@ interface UseAssistantContext { allSystemPrompts: Prompt[]; baseAllow: string[]; baseAllowReplacement: string[]; + docLinks: Omit; defaultAllow: string[]; defaultAllowReplacement: string[]; basePromptContexts: PromptContextTemplate[]; @@ -119,6 +122,7 @@ export const AssistantProvider: React.FC = ({ baseAllowReplacement, defaultAllow, defaultAllowReplacement, + docLinks, basePromptContexts = [], baseQuickPrompts = [], baseSystemPrompts = BASE_SYSTEM_PROMPTS, @@ -240,6 +244,7 @@ export const AssistantProvider: React.FC = ({ conversations, defaultAllow: uniq(defaultAllow), defaultAllowReplacement: uniq(defaultAllowReplacement), + docLinks, getComments, http, promptContexts, @@ -267,6 +272,7 @@ export const AssistantProvider: React.FC = ({ conversations, defaultAllow, defaultAllowReplacement, + docLinks, getComments, http, localStorageQuickPrompts, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/mock/test_providers/test_providers.tsx b/x-pack/packages/kbn-elastic-assistant/impl/mock/test_providers/test_providers.tsx index d3923b2ca8fd1..63fe8cf0d0984 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/mock/test_providers/test_providers.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/mock/test_providers/test_providers.tsx @@ -38,6 +38,10 @@ export const TestProvidersComponent: React.FC = ({ children }) => { baseAllowReplacement={[]} defaultAllow={[]} defaultAllowReplacement={[]} + docLinks={{ + ELASTIC_WEBSITE_URL: 'https://www.elastic.co/', + DOC_LINK_VERSION: 'current', + }} getComments={mockGetComments} getInitialConversations={mockGetInitialConversations} setConversations={jest.fn()} diff --git a/x-pack/packages/kbn-elastic-assistant/tsconfig.json b/x-pack/packages/kbn-elastic-assistant/tsconfig.json index f460832b040d7..05fde2f37756c 100644 --- a/x-pack/packages/kbn-elastic-assistant/tsconfig.json +++ b/x-pack/packages/kbn-elastic-assistant/tsconfig.json @@ -27,5 +27,6 @@ "@kbn/core-notifications-browser", "@kbn/i18n-react", "@kbn/ui-theme", + "@kbn/core-doc-links-browser", ] } diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/test_providers/test_providers.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/test_providers/test_providers.tsx index b2a721329e1fa..48e49e64a3b2c 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/test_providers/test_providers.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/test_providers/test_providers.tsx @@ -39,6 +39,10 @@ export const TestProvidersComponent: React.FC = ({ children }) => { baseAllowReplacement={[]} defaultAllow={[]} defaultAllowReplacement={[]} + docLinks={{ + ELASTIC_WEBSITE_URL: 'https://www.elastic.co/', + DOC_LINK_VERSION: 'current', + }} getComments={mockGetComments} getInitialConversations={mockGetInitialConversations} setConversations={jest.fn()} diff --git a/x-pack/plugins/security_solution/public/app/app.tsx b/x-pack/plugins/security_solution/public/app/app.tsx index ef4e05a5046e4..56927518092ea 100644 --- a/x-pack/plugins/security_solution/public/app/app.tsx +++ b/x-pack/plugins/security_solution/public/app/app.tsx @@ -76,6 +76,8 @@ const StartAppComponent: FC = ({ const nameSpace = `${APP_ID}.${LOCAL_STORAGE_KEY}`; const [darkMode] = useUiSetting$(DEFAULT_DARK_MODE); + + const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = useKibana().services.docLinks; return ( @@ -88,6 +90,7 @@ const StartAppComponent: FC = ({ augmentMessageCodeBlocks={augmentMessageCodeBlocks} defaultAllow={defaultAllow} defaultAllowReplacement={defaultAllowReplacement} + docLinks={{ ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }} baseAllow={DEFAULT_ALLOW} baseAllowReplacement={DEFAULT_ALLOW_REPLACEMENT} basePromptContexts={Object.values(PROMPT_CONTEXTS)} diff --git a/x-pack/plugins/security_solution/public/common/mock/mock_assistant_provider.tsx b/x-pack/plugins/security_solution/public/common/mock/mock_assistant_provider.tsx index 83e34c9bb215f..ec43bddc9e0e4 100644 --- a/x-pack/plugins/security_solution/public/common/mock/mock_assistant_provider.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/mock_assistant_provider.tsx @@ -30,6 +30,10 @@ export const MockAssistantProviderComponent: React.FC = ({ children }) => baseAllow={[]} baseAllowReplacement={[]} defaultAllow={[]} + docLinks={{ + ELASTIC_WEBSITE_URL: 'https://www.elastic.co/', + DOC_LINK_VERSION: 'current', + }} defaultAllowReplacement={[]} getComments={jest.fn(() => [])} getInitialConversations={jest.fn(() => ({}))} From 9d711fb9447e1fe25e7a2f1fa801f82edc95f0b4 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Tue, 11 Jul 2023 17:01:42 -0400 Subject: [PATCH 44/97] feat(slo): render dynamic overview section based on indicator type (#161299) --- .../slo_details/components/header_control.tsx | 13 +- .../slo_details/components/header_title.tsx | 44 ++++- .../pages/slo_details/components/overview.tsx | 171 ------------------ .../overview/apm_indicator_overview.tsx | 85 +++++++++ .../{ => overview}/overview.stories.tsx | 4 +- .../components/overview/overview.tsx | 164 +++++++++++++++++ .../{ => overview}/overview_item.tsx | 18 +- .../slo_details/components/slo_details.tsx | 2 +- ..._sli_apm_params_to_apm_app_deeplink_url.ts | 2 +- .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 12 files changed, 301 insertions(+), 208 deletions(-) delete mode 100644 x-pack/plugins/observability/public/pages/slo_details/components/overview.tsx create mode 100644 x-pack/plugins/observability/public/pages/slo_details/components/overview/apm_indicator_overview.tsx rename x-pack/plugins/observability/public/pages/slo_details/components/{ => overview}/overview.stories.tsx (83%) create mode 100644 x-pack/plugins/observability/public/pages/slo_details/components/overview/overview.tsx rename x-pack/plugins/observability/public/pages/slo_details/components/{ => overview}/overview_item.tsx (62%) diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx index 6e73398527523..22855556997a9 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/components/header_control.tsx @@ -70,15 +70,8 @@ export function HeaderControl({ isLoading, slo }: Props) { const handleNavigateToRules = async () => { const locator = locators.get(rulesLocatorID); - if (slo?.id) { - locator?.navigate( - { - params: { sloId: slo.id }, - }, - { - replace: false, - } - ); + if (slo?.id && locator) { + locator.navigate({ params: { sloId: slo.id } }, { replace: false }); } }; @@ -250,7 +243,7 @@ export function HeaderControl({ isLoading, slo }: Props) { /> - {!!slo && isRuleFlyoutVisible ? ( + {slo && isRuleFlyoutVisible ? ( - {slo.name} - - + <> + + + {slo.name} + + + + + + + + + + + {i18n.translate('xpack.observability.slo.sloDetails.headerTitle.lastUpdatedMessage', { + defaultMessage: 'Last updated on', + })} + +   + {moment(slo.updatedAt).format('ll')} + + + + + + {i18n.translate('xpack.observability.slo.sloDetails.headerTitle.createdMessage', { + defaultMessage: 'Created on', + })} + +   + {moment(slo.createdAt).format('ll')} + + - + ); } diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/overview.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/overview.tsx deleted file mode 100644 index d35325e38a00e..0000000000000 --- a/x-pack/plugins/observability/public/pages/slo_details/components/overview.tsx +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText } from '@elastic/eui'; -import numeral from '@elastic/numeral'; -import { i18n } from '@kbn/i18n'; -import { - occurrencesBudgetingMethodSchema, - rollingTimeWindowTypeSchema, - SLOWithSummaryResponse, -} from '@kbn/slo-schema'; -import moment from 'moment'; -import React from 'react'; -import { useKibana } from '../../../utils/kibana_react'; -import { - BUDGETING_METHOD_OCCURRENCES, - BUDGETING_METHOD_TIMESLICES, - toDurationAdverbLabel, - toDurationLabel, - toIndicatorTypeLabel, -} from '../../../utils/slo/labels'; -import { OverviewItem } from './overview_item'; - -export interface Props { - slo: SLOWithSummaryResponse; -} - -export function Overview({ slo }: Props) { - const { uiSettings } = useKibana().services; - const dateFormat = uiSettings.get('dateFormat'); - const percentFormat = uiSettings.get('format:percent:defaultPattern'); - const hasNoData = slo.summary.status === 'NO_DATA'; - - return ( - - - - - {i18n.translate( - 'xpack.observability.slo.sloDetails.overview.observedValueSubtitle', - { - defaultMessage: '{value} (objective is {objective})', - values: { - value: hasNoData ? '-' : numeral(slo.summary.sliValue).format(percentFormat), - objective: numeral(slo.objective.target).format(percentFormat), - }, - } - )} - - } - /> - {toIndicatorTypeLabel(slo.indicator.type)}} - /> - - {BUDGETING_METHOD_OCCURRENCES} - ) : ( - - {BUDGETING_METHOD_TIMESLICES} ( - {i18n.translate( - 'xpack.observability.slo.sloDetails.overview.timeslicesBudgetingMethodDetails', - { - defaultMessage: '{duration} slices, {target} target', - values: { - duration: toDurationLabel(slo.objective.timesliceWindow!), - target: numeral(slo.objective.timesliceTarget!).format(percentFormat), - }, - } - )} - ) - - ) - } - /> - - - - {!!slo.description ? slo.description : '-'}} - /> - {moment(slo.createdAt).format(dateFormat)}} - /> - {moment(slo.updatedAt).format(dateFormat)}} - /> - 0 ? ( - - {slo.tags.map((tag) => ( - - {tag} - - ))} - - ) : ( - - - ) - } - /> - - - - ); -} - -function toTimeWindowLabel(timeWindow: SLOWithSummaryResponse['timeWindow']): string { - if (rollingTimeWindowTypeSchema.is(timeWindow.type)) { - return i18n.translate('xpack.observability.slo.sloDetails.overview.rollingTimeWindow', { - defaultMessage: '{duration} rolling', - values: { - duration: toDurationLabel(timeWindow.duration), - }, - }); - } - - return i18n.translate('xpack.observability.slo.sloDetails.overview.calendarAlignedTimeWindow', { - defaultMessage: '{duration} calendar aligned', - values: { - duration: toDurationAdverbLabel(timeWindow.duration), - }, - }); -} diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/overview/apm_indicator_overview.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/overview/apm_indicator_overview.tsx new file mode 100644 index 0000000000000..097d800f1202f --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slo_details/components/overview/apm_indicator_overview.tsx @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { APMTransactionDurationIndicator, APMTransactionErrorRateIndicator } from '@kbn/slo-schema'; +import React from 'react'; +import { useKibana } from '../../../../utils/kibana_react'; +import { convertSliApmParamsToApmAppDeeplinkUrl } from '../../../../utils/slo/convert_sli_apm_params_to_apm_app_deeplink_url'; +import { OverviewItem } from './overview_item'; + +interface Props { + indicator: APMTransactionDurationIndicator | APMTransactionErrorRateIndicator; +} + +export function ApmIndicatorOverview({ indicator }: Props) { + const { + http: { basePath }, + } = useKibana().services; + const { service, transactionType, transactionName, environment, filter } = indicator.params; + + const link = basePath.prepend( + convertSliApmParamsToApmAppDeeplinkUrl({ + environment, + filter, + service, + transactionName, + transactionType, + }) + ); + + return ( + + + + {i18n.translate( + 'xpack.observability.slo.sloDetails.overview.apmSource.serviceLabel', + { defaultMessage: 'service: {value}', values: { value: service } } + )} + + + {environment !== '*' && ( + + + {i18n.translate( + 'xpack.observability.slo.sloDetails.overview.apmSource.environmentLabel', + { defaultMessage: 'environment: {value}', values: { value: environment } } + )} + + + )} + {transactionType !== '*' && ( + + + {i18n.translate( + 'xpack.observability.slo.sloDetails.overview.apmSource.transactionTypeLabel', + { defaultMessage: 'transactionType: {value}', values: { value: transactionType } } + )} + + + )} + {transactionName !== '*' && ( + + + {i18n.translate( + 'xpack.observability.slo.sloDetails.overview.apmSource.transactionNameLabel', + { defaultMessage: 'transactionName: {value}', values: { value: transactionName } } + )} + + + )} + + } + /> + ); +} diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/overview.stories.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/overview/overview.stories.tsx similarity index 83% rename from x-pack/plugins/observability/public/pages/slo_details/components/overview.stories.tsx rename to x-pack/plugins/observability/public/pages/slo_details/components/overview/overview.stories.tsx index 3a3666d901304..c393846e23a7d 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/components/overview.stories.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/components/overview/overview.stories.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { ComponentStory } from '@storybook/react'; -import { KibanaReactStorybookDecorator } from '../../../utils/kibana_react.storybook_decorator'; -import { buildSlo } from '../../../data/slo/slo'; +import { KibanaReactStorybookDecorator } from '../../../../utils/kibana_react.storybook_decorator'; +import { buildSlo } from '../../../../data/slo/slo'; import { Overview as Component, Props } from './overview'; export default { diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/overview/overview.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/overview/overview.tsx new file mode 100644 index 0000000000000..f3a6abb829984 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slo_details/components/overview/overview.tsx @@ -0,0 +1,164 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiBadge, + EuiFlexGrid, + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + EuiText, + useIsWithinBreakpoints, +} from '@elastic/eui'; +import numeral from '@elastic/numeral'; +import { i18n } from '@kbn/i18n'; +import { + occurrencesBudgetingMethodSchema, + rollingTimeWindowTypeSchema, + SLOWithSummaryResponse, +} from '@kbn/slo-schema'; +import React from 'react'; +import { useKibana } from '../../../../utils/kibana_react'; +import { + BUDGETING_METHOD_OCCURRENCES, + BUDGETING_METHOD_TIMESLICES, + toDurationAdverbLabel, + toDurationLabel, + toIndicatorTypeLabel, +} from '../../../../utils/slo/labels'; +import { ApmIndicatorOverview } from './apm_indicator_overview'; + +import { OverviewItem } from './overview_item'; + +export interface Props { + slo: SLOWithSummaryResponse; +} + +export function Overview({ slo }: Props) { + const isMobile = useIsWithinBreakpoints(['xs', 's']); + const { uiSettings } = useKibana().services; + const percentFormat = uiSettings.get('format:percent:defaultPattern'); + const hasNoData = slo.summary.status === 'NO_DATA'; + + let IndicatorOverview = null; + switch (slo.indicator.type) { + case 'sli.apm.transactionDuration': + case 'sli.apm.transactionErrorRate': + IndicatorOverview = ; + break; + } + + return ( + + + + {i18n.translate('xpack.observability.slo.sloDetails.overview.observedValueSubtitle', { + defaultMessage: '{value} (objective is {objective})', + values: { + value: hasNoData ? '-' : numeral(slo.summary.sliValue).format(percentFormat), + objective: numeral(slo.objective.target).format(percentFormat), + }, + })} + + } + /> + {toIndicatorTypeLabel(slo.indicator.type)}} + /> + + {BUDGETING_METHOD_OCCURRENCES} + ) : ( + + {BUDGETING_METHOD_TIMESLICES} ( + {i18n.translate( + 'xpack.observability.slo.sloDetails.overview.timeslicesBudgetingMethodDetails', + { + defaultMessage: '{duration} slices, {target} target', + values: { + duration: toDurationLabel(slo.objective.timesliceWindow!), + target: numeral(slo.objective.timesliceTarget!).format(percentFormat), + }, + } + )} + ) + + ) + } + /> + {!!slo.description ? slo.description : '-'}} + /> + 0 ? ( + + {slo.tags.map((tag) => ( + + {tag} + + ))} + + ) : ( + - + ) + } + /> + {IndicatorOverview} + + + ); +} + +function toTimeWindowLabel(timeWindow: SLOWithSummaryResponse['timeWindow']): string { + if (rollingTimeWindowTypeSchema.is(timeWindow.type)) { + return i18n.translate('xpack.observability.slo.sloDetails.overview.rollingTimeWindow', { + defaultMessage: '{duration} rolling', + values: { + duration: toDurationLabel(timeWindow.duration), + }, + }); + } + + return i18n.translate('xpack.observability.slo.sloDetails.overview.calendarAlignedTimeWindow', { + defaultMessage: '{duration} calendar aligned', + values: { + duration: toDurationAdverbLabel(timeWindow.duration), + }, + }); +} diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/overview_item.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/overview/overview_item.tsx similarity index 62% rename from x-pack/plugins/observability/public/pages/slo_details/components/overview_item.tsx rename to x-pack/plugins/observability/public/pages/slo_details/components/overview/overview_item.tsx index 8578dffcd3a90..eda89ecd8b7fc 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/components/overview_item.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/components/overview/overview_item.tsx @@ -15,15 +15,13 @@ export interface Props { export function OverviewItem({ title, subtitle }: Props) { return ( - - - - - {title} - - - {subtitle} - - + + + + {title} + + + {subtitle} + ); } diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/slo_details.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/slo_details.tsx index 516536fb15945..48cb87a9c8ec9 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/components/slo_details.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/components/slo_details.tsx @@ -21,7 +21,7 @@ import { useFetchActiveAlerts } from '../../../hooks/slo/use_fetch_active_alerts import { formatHistoricalData } from '../../../utils/slo/chart_data_formatter'; import { useFetchHistoricalSummary } from '../../../hooks/slo/use_fetch_historical_summary'; import { ErrorBudgetChartPanel } from './error_budget_chart_panel'; -import { Overview as Overview } from './overview'; +import { Overview } from './overview/overview'; import { SliChartPanel } from './sli_chart_panel'; import { SloDetailsAlerts } from './slo_detail_alerts'; import { BurnRates } from './burn_rates'; diff --git a/x-pack/plugins/observability/public/utils/slo/convert_sli_apm_params_to_apm_app_deeplink_url.ts b/x-pack/plugins/observability/public/utils/slo/convert_sli_apm_params_to_apm_app_deeplink_url.ts index d15096cc59a01..0448d786144c0 100644 --- a/x-pack/plugins/observability/public/utils/slo/convert_sli_apm_params_to_apm_app_deeplink_url.ts +++ b/x-pack/plugins/observability/public/utils/slo/convert_sli_apm_params_to_apm_app_deeplink_url.ts @@ -6,7 +6,7 @@ */ interface Props { - duration: string; + duration?: string; environment: string; filter: string | undefined; service: string; diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index ce920e7dedced..dce1d4c5a02a2 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -26771,13 +26771,11 @@ "xpack.observability.slo.sloDetails.headerControl.edit": "Modifier", "xpack.observability.slo.sloDetails.headerControl.manageRules": "Gérer les règles", "xpack.observability.slo.sloDetails.overview.budgetingMethodTitle": "Méthode de budgétisation", - "xpack.observability.slo.sloDetails.overview.createdAtTitle": "Créé à", "xpack.observability.slo.sloDetails.overview.descriptionTitle": "Description", "xpack.observability.slo.sloDetails.overview.indicatorTypeTitle": "Type d’indicateur", "xpack.observability.slo.sloDetails.overview.observedValueTitle": "Valeur observée", "xpack.observability.slo.sloDetails.overview.tagsTitle": "Balises", "xpack.observability.slo.sloDetails.overview.timeWindowTitle": "Fenêtre temporelle", - "xpack.observability.slo.sloDetails.overview.updatedAtTitle": "Dernière mise à jour à", "xpack.observability.slo.sloDetails.sliHistoryChartPanel.chartTitle": "Valeur SLI", "xpack.observability.slo.sloDetails.sliHistoryChartPanel.current": "Valeur observée", "xpack.observability.slo.sloDetails.sliHistoryChartPanel.objective": "Objectif", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index b091a7965f618..a17cd63a4c62c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -26757,13 +26757,11 @@ "xpack.observability.slo.sloDetails.headerControl.edit": "編集", "xpack.observability.slo.sloDetails.headerControl.manageRules": "ルールの管理", "xpack.observability.slo.sloDetails.overview.budgetingMethodTitle": "予算設定方法", - "xpack.observability.slo.sloDetails.overview.createdAtTitle": "作成日時:", "xpack.observability.slo.sloDetails.overview.descriptionTitle": "説明", "xpack.observability.slo.sloDetails.overview.indicatorTypeTitle": "インジケータータイプ", "xpack.observability.slo.sloDetails.overview.observedValueTitle": "観測された値", "xpack.observability.slo.sloDetails.overview.tagsTitle": "タグ", "xpack.observability.slo.sloDetails.overview.timeWindowTitle": "時間枠", - "xpack.observability.slo.sloDetails.overview.updatedAtTitle": "最終更新日時", "xpack.observability.slo.sloDetails.sliHistoryChartPanel.chartTitle": "SLI値", "xpack.observability.slo.sloDetails.sliHistoryChartPanel.current": "観測された値", "xpack.observability.slo.sloDetails.sliHistoryChartPanel.objective": "目的", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 32bfb741eaaf7..f8262933b3a83 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -26755,13 +26755,11 @@ "xpack.observability.slo.sloDetails.headerControl.edit": "编辑", "xpack.observability.slo.sloDetails.headerControl.manageRules": "管理规则", "xpack.observability.slo.sloDetails.overview.budgetingMethodTitle": "预算编制方法", - "xpack.observability.slo.sloDetails.overview.createdAtTitle": "创建于", "xpack.observability.slo.sloDetails.overview.descriptionTitle": "描述", "xpack.observability.slo.sloDetails.overview.indicatorTypeTitle": "指标类型", "xpack.observability.slo.sloDetails.overview.observedValueTitle": "观察值", "xpack.observability.slo.sloDetails.overview.tagsTitle": "标签", "xpack.observability.slo.sloDetails.overview.timeWindowTitle": "时间窗口", - "xpack.observability.slo.sloDetails.overview.updatedAtTitle": "上次更新时间", "xpack.observability.slo.sloDetails.sliHistoryChartPanel.chartTitle": "SLI 值", "xpack.observability.slo.sloDetails.sliHistoryChartPanel.current": "观察值", "xpack.observability.slo.sloDetails.sliHistoryChartPanel.objective": "目标", From 88fc4a66271a16808eb6386610ad41c4e43c271c Mon Sep 17 00:00:00 2001 From: Davis Plumlee <56367316+dplumlee@users.noreply.github.com> Date: Tue, 11 Jul 2023 17:11:23 -0400 Subject: [PATCH 45/97] [Security Solution][Detection Alerts] Alert tagging follow-up (#160305) --- .../schemas/common/schemas.ts | 4 +- .../request/set_alert_tags_schema.mock.ts | 5 +- .../schemas/request/set_alert_tags_schema.ts | 12 +- .../e2e/detection_alerts/alert_tags.cy.ts | 7 +- .../cypress/tasks/api_calls/elasticsearch.ts | 18 ++ .../bulk_actions/alert_bulk_tags.test.tsx | 189 +++++++++++++++--- .../toolbar/bulk_actions/alert_bulk_tags.tsx | 84 +++++--- .../toolbar/bulk_actions/helpers.ts | 18 -- .../toolbar/bulk_actions/reducer.ts | 59 ++++++ .../toolbar/bulk_actions/translations.ts | 17 +- .../use_bulk_alert_tags_items.test.tsx | 99 +++++++++ .../use_bulk_alert_tags_items.tsx | 89 ++++++--- .../bulk_actions/use_set_alert_tags.tsx | 47 +---- .../common/containers/alert_tags/api.ts | 27 +++ .../alert_context_menu.test.tsx | 15 +- .../timeline_actions/alert_context_menu.tsx | 1 - .../use_alert_tags_actions.test.tsx | 168 ++++++++++++++++ .../use_alert_tags_actions.tsx | 13 +- .../take_action_dropdown/index.test.tsx | 8 + .../components/take_action_dropdown/index.tsx | 1 - .../routes/signals/helpers.ts | 10 +- .../signals/set_alert_tags_route.test.ts | 41 +++- .../routes/signals/set_alert_tags_route.ts | 79 ++++---- .../routes/signals/translations.ts | 7 + .../triggers_actions_ui/public/types.ts | 2 +- .../group10/set_alert_tags.ts | 33 ++- .../utils/set_alert_tags.ts | 18 +- 27 files changed, 829 insertions(+), 242 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/reducer.ts create mode 100644 x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.test.tsx create mode 100644 x-pack/plugins/security_solution/public/common/containers/alert_tags/api.ts create mode 100644 x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alert_tags_actions.test.tsx diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts index cb4de5c5c03a4..7e8cb0ebbe58b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts @@ -45,8 +45,8 @@ export type SignalIds = t.TypeOf; // TODO: Can this be more strict or is this is the set of all Elastic Queries? export const signal_status_query = t.object; -export const alert_tag_query = t.record(t.string, t.unknown); -export type AlertTagQuery = t.TypeOf; +export const alert_tag_ids = t.array(t.string); +export type AlertTagIds = t.TypeOf; export const fields = t.array(t.string); export type Fields = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.mock.ts index d66ecbeee20eb..4f3bf93550223 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.mock.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.mock.ts @@ -9,5 +9,6 @@ import type { SetAlertTagsSchema } from './set_alert_tags_schema'; export const getSetAlertTagsRequestMock = ( tagsToAdd: string[] = [], - tagsToRemove: string[] = [] -): SetAlertTagsSchema => ({ tags: { tags_to_add: tagsToAdd, tags_to_remove: tagsToRemove } }); + tagsToRemove: string[] = [], + ids: string[] = [] +): SetAlertTagsSchema => ({ tags: { tags_to_add: tagsToAdd, tags_to_remove: tagsToRemove }, ids }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.ts index 54e5a0b0cd1b6..cb11c8c70c8ab 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/set_alert_tags_schema.ts @@ -7,16 +7,14 @@ import * as t from 'io-ts'; -import { alert_tag_query, alert_tags } from '../common/schemas'; +import { alert_tag_ids, alert_tags } from '../common/schemas'; -export const setAlertTagsSchema = t.intersection([ +export const setAlertTagsSchema = t.exact( t.type({ tags: alert_tags, - }), - t.partial({ - query: alert_tag_query, - }), -]); + ids: alert_tag_ids, + }) +); export type SetAlertTagsSchema = t.TypeOf; export type SetAlertTagsSchemaDecoded = SetAlertTagsSchema; diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/alert_tags.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/alert_tags.cy.ts index 2c11f7276785a..2dd518dc4bd1e 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/alert_tags.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_alerts/alert_tags.cy.ts @@ -25,7 +25,7 @@ import { } from '../../screens/alerts'; import { esArchiverLoad, esArchiverResetKibana, esArchiverUnload } from '../../tasks/es_archiver'; -describe.skip('Alert tagging', () => { +describe('Alert tagging', () => { before(() => { cleanKibana(); esArchiverResetKibana(); @@ -51,7 +51,6 @@ describe.skip('Alert tagging', () => { clickAlertTag('Duplicate'); updateAlertTags(); cy.get(ALERTS_TABLE_ROW_LOADER).should('not.exist'); - waitForAlertsToPopulate(); selectNumberOfAlerts(1); openAlertTaggingBulkActionMenu(); cy.get(SELECTED_ALERT_TAG).contains('Duplicate'); @@ -59,7 +58,6 @@ describe.skip('Alert tagging', () => { clickAlertTag('Duplicate'); updateAlertTags(); cy.get(ALERTS_TABLE_ROW_LOADER).should('not.exist'); - waitForAlertsToPopulate(); selectNumberOfAlerts(1); openAlertTaggingBulkActionMenu(); cy.get(UNSELECTED_ALERT_TAG).first().contains('Duplicate'); @@ -72,7 +70,6 @@ describe.skip('Alert tagging', () => { clickAlertTag('Duplicate'); updateAlertTags(); cy.get(ALERTS_TABLE_ROW_LOADER).should('not.exist'); - waitForAlertsToPopulate(); // Then add tags to both alerts selectNumberOfAlerts(2); openAlertTaggingBulkActionMenu(); @@ -80,7 +77,6 @@ describe.skip('Alert tagging', () => { clickAlertTag('Duplicate'); updateAlertTags(); cy.get(ALERTS_TABLE_ROW_LOADER).should('not.exist'); - waitForAlertsToPopulate(); selectNumberOfAlerts(2); openAlertTaggingBulkActionMenu(); cy.get(SELECTED_ALERT_TAG).contains('Duplicate'); @@ -102,7 +98,6 @@ describe.skip('Alert tagging', () => { clickAlertTag('Duplicate'); // Clicking twice will return to unselected state updateAlertTags(); cy.get(ALERTS_TABLE_ROW_LOADER).should('not.exist'); - waitForAlertsToPopulate(); selectNumberOfAlerts(2); openAlertTaggingBulkActionMenu(); cy.get(UNSELECTED_ALERT_TAG).first().contains('Duplicate'); diff --git a/x-pack/plugins/security_solution/cypress/tasks/api_calls/elasticsearch.ts b/x-pack/plugins/security_solution/cypress/tasks/api_calls/elasticsearch.ts index 84d8763c763a2..7312339497f2c 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/api_calls/elasticsearch.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/api_calls/elasticsearch.ts @@ -51,3 +51,21 @@ export const waitForNewDocumentToBeIndexed = (index: string, initialNumberOfDocu { interval: 500, timeout: 12000 } ); }; + +export const refreshIndex = (index: string) => { + cy.waitUntil( + () => + rootRequest({ + method: 'POST', + url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_refresh`, + headers: { 'kbn-xsrf': 'cypress-creds' }, + failOnStatusCode: false, + }).then((response) => { + if (response.status !== 200) { + return false; + } + return true; + }), + { interval: 500, timeout: 12000 } + ); +}; diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.test.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.test.tsx index cce59e0ce30db..09d90c1284a0e 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.test.tsx @@ -5,21 +5,17 @@ * 2.0. */ -import { render } from '@testing-library/react'; +import type { TimelineItem } from '@kbn/timelines-plugin/common'; +import { act, fireEvent, render } from '@testing-library/react'; import React from 'react'; import { TestProviders } from '../../../mock'; import { useUiSetting$ } from '../../../lib/kibana'; +import * as helpers from './helpers'; import { BulkAlertTagsPanel } from './alert_bulk_tags'; import { ALERT_WORKFLOW_TAGS } from '@kbn/rule-data-utils'; -import { useAppToasts } from '../../../hooks/use_app_toasts'; -import { useSetAlertTags } from './use_set_alert_tags'; -import { getUpdateAlertsQuery } from './helpers'; jest.mock('../../../lib/kibana'); -jest.mock('../../../hooks/use_app_toasts'); -jest.mock('./use_set_alert_tags'); -jest.mock('./helpers'); const mockTagItems = [ { @@ -29,27 +25,172 @@ const mockTagItems = [ }, ]; -(useUiSetting$ as jest.Mock).mockReturnValue(['default-test-tag']); -(useAppToasts as jest.Mock).mockReturnValue({ - addError: jest.fn(), - addSuccess: jest.fn(), - addWarning: jest.fn(), -}); -(useSetAlertTags as jest.Mock).mockReturnValue([false, jest.fn()]); -(getUpdateAlertsQuery as jest.Mock).mockReturnValue({ query: {} }); +(useUiSetting$ as jest.Mock).mockReturnValue([['default-test-tag-1', 'default-test-tag-2']]); +const createInitialTagsState = jest.spyOn(helpers, 'createInitialTagsState'); + +const renderTagsMenu = ( + tags: TimelineItem[], + closePopover: () => void = jest.fn(), + onSubmit: () => Promise = jest.fn(), + setIsLoading: () => void = jest.fn() +) => { + return render( + + + + ); +}; describe('BulkAlertTagsPanel', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + test('it renders', () => { - const wrapper = render( - - {}} - closePopoverMenu={() => {}} - /> - - ); + const wrapper = renderTagsMenu(mockTagItems); expect(wrapper.getByTestId('alert-tags-selectable-menu')).toBeInTheDocument(); + expect(createInitialTagsState).toHaveBeenCalled(); + }); + + test('it renders a valid state when existing alert tags are passed', () => { + const mockTags = [ + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['default-test-tag-1'] }], + ecs: { _id: 'test-id' }, + }, + ]; + const wrapper = renderTagsMenu(mockTags); + + expect(wrapper.getByTestId('selected-alert-tag')).toHaveTextContent('default-test-tag-1'); + expect(wrapper.getByTestId('unselected-alert-tag')).toHaveTextContent('default-test-tag-2'); + }); + + test('it renders a valid state when multiple alerts with tags are passed', () => { + const mockTags = [ + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['default-test-tag-1'] }], + ecs: { _id: 'test-id' }, + }, + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['default-test-tag-1', 'default-test-tag-2'] }], + ecs: { _id: 'test-id' }, + }, + ]; + const wrapper = renderTagsMenu(mockTags); + + expect(wrapper.getByTestId('selected-alert-tag')).toHaveTextContent('default-test-tag-1'); + expect(wrapper.getByTestId('mixed-alert-tag')).toHaveTextContent('default-test-tag-2'); + }); + + test('it calls expected functions on submit when nothing has changed', () => { + const mockedClosePopover = jest.fn(); + const mockedOnSubmit = jest.fn(); + const mockedSetIsLoading = jest.fn(); + + const mockTags = [ + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['default-test-tag-1'] }], + ecs: { _id: 'test-id' }, + }, + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['default-test-tag-1', 'default-test-tag-2'] }], + ecs: { _id: 'test-id' }, + }, + ]; + const wrapper = renderTagsMenu( + mockTags, + mockedClosePopover, + mockedOnSubmit, + mockedSetIsLoading + ); + + act(() => { + fireEvent.click(wrapper.getByTestId('alert-tags-update-button')); + }); + expect(mockedClosePopover).toHaveBeenCalled(); + expect(mockedOnSubmit).not.toHaveBeenCalled(); + expect(mockedSetIsLoading).not.toHaveBeenCalled(); + }); + + test('it updates state correctly', () => { + const mockTags = [ + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['default-test-tag-1'] }], + ecs: { _id: 'test-id' }, + }, + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['default-test-tag-1', 'default-test-tag-2'] }], + ecs: { _id: 'test-id' }, + }, + ]; + const wrapper = renderTagsMenu(mockTags); + + expect(wrapper.getByTitle('default-test-tag-1')).toBeChecked(); + act(() => { + fireEvent.click(wrapper.getByText('default-test-tag-1')); + }); + expect(wrapper.getByTitle('default-test-tag-1')).not.toBeChecked(); + + expect(wrapper.getByTitle('default-test-tag-2')).not.toBeChecked(); + act(() => { + fireEvent.click(wrapper.getByText('default-test-tag-2')); + }); + expect(wrapper.getByTitle('default-test-tag-2')).toBeChecked(); + }); + + test('it calls expected functions on submit when alerts have changed', () => { + const mockedClosePopover = jest.fn(); + const mockedOnSubmit = jest.fn(); + const mockedSetIsLoading = jest.fn(); + + const mockTags = [ + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['default-test-tag-1'] }], + ecs: { _id: 'test-id' }, + }, + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['default-test-tag-1', 'default-test-tag-2'] }], + ecs: { _id: 'test-id' }, + }, + ]; + const wrapper = renderTagsMenu( + mockTags, + mockedClosePopover, + mockedOnSubmit, + mockedSetIsLoading + ); + act(() => { + fireEvent.click(wrapper.getByText('default-test-tag-1')); + }); + act(() => { + fireEvent.click(wrapper.getByText('default-test-tag-2')); + }); + + act(() => { + fireEvent.click(wrapper.getByTestId('alert-tags-update-button')); + }); + expect(mockedClosePopover).toHaveBeenCalled(); + expect(mockedOnSubmit).toHaveBeenCalled(); + expect(mockedOnSubmit).toHaveBeenCalledWith( + { tags_to_add: ['default-test-tag-2'], tags_to_remove: ['default-test-tag-1'] }, + ['test-id', 'test-id'], + expect.anything(), // An anonymous callback defined in the onSubmit function + mockedSetIsLoading + ); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.tsx index 28abb87bc79c8..bdb5c1d2d5f01 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/alert_bulk_tags.tsx @@ -8,14 +8,15 @@ import type { EuiSelectableOption } from '@elastic/eui'; import { EuiPopoverTitle, EuiSelectable, EuiButton } from '@elastic/eui'; import type { TimelineItem } from '@kbn/timelines-plugin/common'; -import React, { memo, useCallback, useMemo, useState } from 'react'; +import React, { memo, useCallback, useMemo, useReducer } from 'react'; import { ALERT_WORKFLOW_TAGS } from '@kbn/rule-data-utils'; import type { EuiSelectableOnChangeEvent } from '@elastic/eui/src/components/selectable/selectable'; import { DEFAULT_ALERT_TAGS_KEY } from '../../../../../common/constants'; import { useUiSetting$ } from '../../../lib/kibana'; -import { useSetAlertTags } from './use_set_alert_tags'; import * as i18n from './translations'; import { createInitialTagsState } from './helpers'; +import { createAlertTagsReducer, initialState } from './reducer'; +import type { SetAlertTagsFunc } from './use_set_alert_tags'; interface BulkAlertTagsPanelComponentProps { alertItems: TimelineItem[]; @@ -24,6 +25,7 @@ interface BulkAlertTagsPanelComponentProps { refresh?: () => void; clearSelection?: () => void; closePopoverMenu: () => void; + onSubmit: SetAlertTagsFunc; } const BulkAlertTagsPanelComponent: React.FC = ({ alertItems, @@ -32,10 +34,10 @@ const BulkAlertTagsPanelComponent: React.FC = setIsLoading, clearSelection, closePopoverMenu, + onSubmit, }) => { const [defaultAlertTagOptions] = useUiSetting$(DEFAULT_ALERT_TAGS_KEY); - const [, setAlertTags] = useSetAlertTags(); const existingTags = useMemo( () => alertItems.map( @@ -43,20 +45,40 @@ const BulkAlertTagsPanelComponent: React.FC = ), [alertItems] ); - const initialTagsState = useMemo( - () => createInitialTagsState(existingTags, defaultAlertTagOptions), - [existingTags, defaultAlertTagOptions] + const [{ selectableAlertTags, tagsToAdd, tagsToRemove }, dispatch] = useReducer( + createAlertTagsReducer(), + { + ...initialState, + selectableAlertTags: createInitialTagsState(existingTags, defaultAlertTagOptions), + tagsToAdd: new Set(), + tagsToRemove: new Set(), + } ); - const tagsToAdd: Set = useMemo(() => new Set(), []); - const tagsToRemove: Set = useMemo(() => new Set(), []); + const addAlertTag = useCallback( + (value: string) => { + dispatch({ type: 'addAlertTag', value }); + }, + [dispatch] + ); - const [selectableAlertTags, setSelectableAlertTags] = - useState(initialTagsState); + const removeAlertTag = useCallback( + (value: string) => { + dispatch({ type: 'removeAlertTag', value }); + }, + [dispatch] + ); - const onTagsUpdate = useCallback(() => { - closePopoverMenu(); + const setSelectableAlertTags = useCallback( + (value: EuiSelectableOption[]) => { + dispatch({ type: 'setSelectableAlertTags', value }); + }, + [dispatch] + ); + + const onTagsUpdate = useCallback(async () => { if (tagsToAdd.size === 0 && tagsToRemove.size === 0) { + closePopoverMenu(); return; } const tagsToAddArray = Array.from(tagsToAdd); @@ -68,35 +90,37 @@ const BulkAlertTagsPanelComponent: React.FC = if (refresh) refresh(); if (clearSelection) clearSelection(); }; - if (setAlertTags != null) { - setAlertTags(tags, ids, onSuccess, setIsLoading); + if (onSubmit != null) { + closePopoverMenu(); + await onSubmit(tags, ids, onSuccess, setIsLoading); } }, [ closePopoverMenu, tagsToAdd, tagsToRemove, alertItems, - setAlertTags, refetchQuery, refresh, clearSelection, setIsLoading, + onSubmit, ]); - const handleTagsOnChange = ( - newOptions: EuiSelectableOption[], - event: EuiSelectableOnChangeEvent, - changedOption: EuiSelectableOption - ) => { - if (changedOption.checked === 'on') { - tagsToAdd.add(changedOption.label); - tagsToRemove.delete(changedOption.label); - } else if (!changedOption.checked) { - tagsToRemove.add(changedOption.label); - tagsToAdd.delete(changedOption.label); - } - setSelectableAlertTags(newOptions); - }; + const handleTagsOnChange = useCallback( + ( + newOptions: EuiSelectableOption[], + event: EuiSelectableOnChangeEvent, + changedOption: EuiSelectableOption + ) => { + if (changedOption.checked === 'on') { + addAlertTag(changedOption.label); + } else if (!changedOption.checked) { + removeAlertTag(changedOption.label); + } + setSelectableAlertTags(newOptions); + }, + [addAlertTag, removeAlertTag, setSelectableAlertTags] + ); return ( <> @@ -125,7 +149,7 @@ const BulkAlertTagsPanelComponent: React.FC = size="s" onClick={onTagsUpdate} > - {i18n.ALERT_TAGS_UPDATE_BUTTON_MESSAGE} + {i18n.ALERT_TAGS_APPLY_BUTTON_MESSAGE} ); diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/helpers.ts b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/helpers.ts index 8c81792620cfa..39608b4fc7f2b 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/helpers.ts @@ -45,21 +45,3 @@ export const createInitialTagsState = (existingTags: string[][], defaultTags: st }) .sort(checkedSortCallback); }; - -/** - * @deprecated - * Please avoid using update_by_query API with `refresh:true` on serverless, use `_bulk` update by id instead. - */ -export const getUpdateAlertsQuery = (eventIds: Readonly) => { - return { - query: { - bool: { - filter: { - terms: { - _id: eventIds, - }, - }, - }, - }, - }; -}; diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/reducer.ts b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/reducer.ts new file mode 100644 index 0000000000000..a233579e084fa --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/reducer.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EuiSelectableOption } from '@elastic/eui'; + +export interface State { + selectableAlertTags: EuiSelectableOption[]; + tagsToAdd: Set; + tagsToRemove: Set; +} + +export const initialState: State = { + selectableAlertTags: [], + tagsToAdd: new Set(), + tagsToRemove: new Set(), +}; + +export type Action = + | { + type: 'addAlertTag'; + value: string; + } + | { + type: 'removeAlertTag'; + value: string; + } + | { + type: 'setSelectableAlertTags'; + value: EuiSelectableOption[]; + }; + +export const createAlertTagsReducer = + () => + (state: State, action: Action): State => { + switch (action.type) { + case 'addAlertTag': { + const { value } = action; + state.tagsToAdd.add(value); + state.tagsToRemove.delete(value); + return state; + } + case 'removeAlertTag': { + const { value } = action; + state.tagsToRemove.add(value); + state.tagsToAdd.delete(value); + return state; + } + case 'setSelectableAlertTags': { + const { value } = action; + return { ...state, selectableAlertTags: value }; + } + default: + return state; + } + }; diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/translations.ts b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/translations.ts index 70496f779cb09..a99ad3cb76a43 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/translations.ts @@ -187,20 +187,27 @@ export const ALERT_TAGS_MENU_SEARCH_NO_TAGS_FOUND = i18n.translate( export const ALERT_TAGS_MENU_EMPTY = i18n.translate( 'xpack.securitySolution.bulkActions.alertTagsMenuEmptyMessage', { - defaultMessage: 'No tag options exist, add tag options in Advanced Settings.', + defaultMessage: 'No alert tag options exist, add tag options in Kibana Advanced Settings.', } ); -export const ALERT_TAGS_UPDATE_BUTTON_MESSAGE = i18n.translate( - 'xpack.securitySolution.bulkActions.alertTagsUpdateButtonMessage', +export const ALERT_TAGS_APPLY_BUTTON_MESSAGE = i18n.translate( + 'xpack.securitySolution.bulkActions.alertTagsApplyButtonMessage', { - defaultMessage: 'Update tags', + defaultMessage: 'Apply tags', } ); export const ALERT_TAGS_CONTEXT_MENU_ITEM_TITLE = i18n.translate( 'xpack.securitySolution.bulkActions.alertTagsContextMenuItemTitle', { - defaultMessage: 'Manage alert tags', + defaultMessage: 'Apply alert tags', + } +); + +export const ALERT_TAGS_CONTEXT_MENU_ITEM_TOOLTIP_INFO = i18n.translate( + 'xpack.securitySolution.bulkActions.alertTagsContextMenuItemTooltip', + { + defaultMessage: 'Change alert tag options in Kibana Advanced Settings.', } ); diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.test.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.test.tsx new file mode 100644 index 0000000000000..3cbc54cf24f12 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.test.tsx @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ALERT_WORKFLOW_TAGS } from '@kbn/rule-data-utils'; +import { TestProviders } from '@kbn/timelines-plugin/public/mock'; +import { act, fireEvent, render } from '@testing-library/react'; +import { renderHook } from '@testing-library/react-hooks'; +import type { + UseBulkAlertTagsItemsProps, + UseBulkAlertTagsPanel, +} from './use_bulk_alert_tags_items'; +import { useBulkAlertTagsItems } from './use_bulk_alert_tags_items'; +import { useSetAlertTags } from './use_set_alert_tags'; +import { useUiSetting$ } from '../../../lib/kibana'; + +jest.mock('./use_set_alert_tags'); +jest.mock('../../../lib/kibana'); + +const defaultProps: UseBulkAlertTagsItemsProps = { + refetch: () => {}, +}; + +const mockTagItems = [ + { + _id: 'test-id', + data: [{ field: ALERT_WORKFLOW_TAGS, value: ['tag-1', 'tag-2'] }], + ecs: { _id: 'test-id', _index: 'test-index' }, + }, +]; + +const renderPanel = (panel: UseBulkAlertTagsPanel) => { + const content = panel.renderContent({ + closePopoverMenu: jest.fn(), + setIsBulkActionsLoading: jest.fn(), + alertItems: mockTagItems, + }); + return render(content); +}; + +describe('useBulkAlertTagsItems', () => { + beforeEach(() => { + (useSetAlertTags as jest.Mock).mockReturnValue(jest.fn()); + (useUiSetting$ as jest.Mock).mockReturnValue([['default-test-tag-1']]); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should render alert tagging actions', () => { + const { result } = renderHook(() => useBulkAlertTagsItems(defaultProps), { + wrapper: TestProviders, + }); + expect(result.current.alertTagsItems.length).toEqual(1); + expect(result.current.alertTagsPanels.length).toEqual(1); + + expect(result.current.alertTagsItems[0]['data-test-subj']).toEqual( + 'alert-tags-context-menu-item' + ); + expect(result.current.alertTagsPanels[0]['data-test-subj']).toEqual( + 'alert-tags-context-menu-panel' + ); + }); + + it('should still render alert tagging panel when useSetAlertTags is null', () => { + (useSetAlertTags as jest.Mock).mockReturnValue(null); + const { result } = renderHook(() => useBulkAlertTagsItems(defaultProps), { + wrapper: TestProviders, + }); + + expect(result.current.alertTagsPanels[0]['data-test-subj']).toEqual( + 'alert-tags-context-menu-panel' + ); + const wrapper = renderPanel(result.current.alertTagsPanels[0]); + expect(wrapper.getByTestId('alert-tags-selectable-menu')).toBeInTheDocument(); + }); + + it('should call setAlertTags on submit', () => { + const mockSetAlertTags = jest.fn(); + (useSetAlertTags as jest.Mock).mockReturnValue(mockSetAlertTags); + const { result } = renderHook(() => useBulkAlertTagsItems(defaultProps), { + wrapper: TestProviders, + }); + + const wrapper = renderPanel(result.current.alertTagsPanels[0]); + expect(wrapper.getByTestId('alert-tags-selectable-menu')).toBeInTheDocument(); + act(() => { + fireEvent.click(wrapper.getByTestId('unselected-alert-tag')); // Won't fire unless component tags selection has been changed + }); + act(() => { + fireEvent.click(wrapper.getByTestId('alert-tags-update-button')); + }); + expect(mockSetAlertTags).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx index 7a9aa1deaf67e..df4d5c37aeeaf 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx @@ -5,16 +5,35 @@ * 2.0. */ +import { EuiFlexGroup, EuiIconTip, EuiFlexItem } from '@elastic/eui'; import type { RenderContentPanelProps } from '@kbn/triggers-actions-ui-plugin/public/types'; -import React from 'react'; +import React, { useCallback, useMemo } from 'react'; import { BulkAlertTagsPanel } from './alert_bulk_tags'; import * as i18n from './translations'; +import { useSetAlertTags } from './use_set_alert_tags'; -interface UseBulkAlertTagsItemsProps { +export interface UseBulkAlertTagsItemsProps { refetch?: () => void; } +export interface UseBulkAlertTagsPanel { + id: number; + title: JSX.Element; + 'data-test-subj': string; + renderContent: (props: RenderContentPanelProps) => JSX.Element; +} + export const useBulkAlertTagsItems = ({ refetch }: UseBulkAlertTagsItemsProps) => { + const setAlertTags = useSetAlertTags(); + const handleOnAlertTagsSubmit = useCallback( + async (tags, ids, onSuccess, setIsLoading) => { + if (setAlertTags) { + await setAlertTags(tags, ids, onSuccess, setIsLoading); + } + }, + [setAlertTags] + ); + const alertTagsItems = [ { key: 'manage-alert-tags', @@ -26,28 +45,50 @@ export const useBulkAlertTagsItems = ({ refetch }: UseBulkAlertTagsItemsProps) = }, ]; - const alertTagsPanels = [ - { - id: 1, - title: i18n.ALERT_TAGS_CONTEXT_MENU_ITEM_TITLE, - renderContent: ({ - alertItems, - refresh, - setIsBulkActionsLoading, - clearSelection, - closePopoverMenu, - }: RenderContentPanelProps) => ( - - ), - }, - ]; + const TitleContent = useMemo( + () => ( + + {i18n.ALERT_TAGS_CONTEXT_MENU_ITEM_TITLE} + + + + + ), + [] + ); + + const renderContent = useCallback( + ({ + alertItems, + refresh, + setIsBulkActionsLoading, + clearSelection, + closePopoverMenu, + }: RenderContentPanelProps) => ( + + ), + [handleOnAlertTagsSubmit, refetch] + ); + + const alertTagsPanels: UseBulkAlertTagsPanel[] = useMemo( + () => [ + { + id: 1, + title: TitleContent, + 'data-test-subj': 'alert-tags-context-menu-panel', + renderContent, + }, + ], + [TitleContent, renderContent] + ); return { alertTagsItems, diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx index 9b211f9c259cc..687c8b17260a5 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_set_alert_tags.tsx @@ -5,16 +5,13 @@ * 2.0. */ -import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { CoreStart } from '@kbn/core/public'; - import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef } from 'react'; import type { AlertTags } from '../../../../../common/detection_engine/schemas/common'; -import { DETECTION_ENGINE_ALERT_TAGS_URL } from '../../../../../common/constants'; import { useAppToasts } from '../../../hooks/use_app_toasts'; import * as i18n from './translations'; -import { getUpdateAlertsQuery } from './helpers'; +import { setAlertTags } from '../../../containers/alert_tags/api'; export type SetAlertTagsFunc = ( tags: AlertTags, @@ -22,7 +19,7 @@ export type SetAlertTagsFunc = ( onSuccess: () => void, setTableLoading: (param: boolean) => void ) => Promise; -export type ReturnSetAlertTags = [boolean, SetAlertTagsFunc | null]; +export type ReturnSetAlertTags = SetAlertTagsFunc | null; /** * Update alert tags by query @@ -37,22 +34,12 @@ export type ReturnSetAlertTags = [boolean, SetAlertTagsFunc | null]; */ export const useSetAlertTags = (): ReturnSetAlertTags => { const { http } = useKibana().services; - const { addSuccess, addError, addWarning } = useAppToasts(); + const { addSuccess, addError } = useAppToasts(); const setAlertTagsRef = useRef(null); - const [isLoading, setIsLoading] = useState(false); const onUpdateSuccess = useCallback( - (updated: number, conflicts: number) => { - if (conflicts > 0) { - addWarning({ - title: i18n.UPDATE_ALERT_TAGS_FAILED(conflicts), - text: i18n.UPDATE_ALERT_TAGS_FAILED_DETAILED(updated, conflicts), - }); - } else { - addSuccess(i18n.UPDATE_ALERT_TAGS_SUCCESS_TOAST(updated)); - } - }, - [addSuccess, addWarning] + (updated: number) => addSuccess(i18n.UPDATE_ALERT_TAGS_SUCCESS_TOAST(updated)), + [addSuccess] ); const onUpdateFailure = useCallback( @@ -67,30 +54,16 @@ export const useSetAlertTags = (): ReturnSetAlertTags => { const abortCtrl = new AbortController(); const onSetAlertTags: SetAlertTagsFunc = async (tags, ids, onSuccess, setTableLoading) => { - const query: Record = getUpdateAlertsQuery(ids).query; try { - setIsLoading(true); setTableLoading(true); - const response = await http.fetch( - DETECTION_ENGINE_ALERT_TAGS_URL, - { - method: 'POST', - body: JSON.stringify({ tags, query }), - signal: abortCtrl.signal, - } - ); + const response = await setAlertTags({ tags, ids, signal: abortCtrl.signal }); if (!ignore) { - setTableLoading(false); onSuccess(); - if (response.version_conflicts && ids.length === 1) { - throw new Error(i18n.BULK_ACTION_FAILED_SINGLE_ALERT); - } - setIsLoading(false); - onUpdateSuccess(response.updated ?? 0, response.version_conflicts ?? 0); + setTableLoading(false); + onUpdateSuccess(response.items.length); } } catch (error) { if (!ignore) { - setIsLoading(false); setTableLoading(false); onUpdateFailure(error); } @@ -104,5 +77,5 @@ export const useSetAlertTags = (): ReturnSetAlertTags => { }; }, [http, onUpdateFailure, onUpdateSuccess]); - return [isLoading, setAlertTagsRef.current]; + return setAlertTagsRef.current; }; diff --git a/x-pack/plugins/security_solution/public/common/containers/alert_tags/api.ts b/x-pack/plugins/security_solution/public/common/containers/alert_tags/api.ts new file mode 100644 index 0000000000000..2d02e43aacb48 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/containers/alert_tags/api.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { estypes } from '@elastic/elasticsearch'; +import { DETECTION_ENGINE_ALERT_TAGS_URL } from '../../../../common/constants'; +import type { AlertTags } from '../../../../common/detection_engine/schemas/common'; +import { KibanaServices } from '../../lib/kibana'; + +export const setAlertTags = async ({ + tags, + ids, + signal, +}: { + tags: AlertTags; + ids: string[]; + signal: AbortSignal | undefined; +}): Promise => { + return KibanaServices.get().http.fetch(DETECTION_ENGINE_ALERT_TAGS_URL, { + method: 'POST', + body: JSON.stringify({ tags, ids }), + signal, + }); +}; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.test.tsx index de43a237c22cf..9907aea709e58 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.test.tsx @@ -95,6 +95,7 @@ const markAsAcknowledgedButton = '[data-test-subj="acknowledged-alert-status"]'; const markAsClosedButton = '[data-test-subj="close-alert-status"]'; const addEndpointEventFilterButton = '[data-test-subj="add-event-filter-menu-item"]'; const openAlertDetailsPageButton = '[data-test-subj="open-alert-details-page-menu-item"]'; +const applyAlertTagsButton = '[data-test-subj="alert-tags-context-menu-item"]'; describe('Alert table context menu', () => { describe('Case actions', () => { @@ -283,7 +284,7 @@ describe('Alert table context menu', () => { }); }); - describe('Open alert details action', () => { + describe('Open alert details action', () => { test('it does not render the open alert details page action if kibana.alert.rule.uuid is not set', () => { const nonAlertProps = { ...props, @@ -320,4 +321,16 @@ describe('Alert table context menu', () => { expect(wrapper.find(openAlertDetailsPageButton).first().exists()).toEqual(true); }); }); + + describe('Apply alert tags action', () => { + test('it renders the apply alert tags action button', () => { + const wrapper = mount(, { + wrappingComponent: TestProviders, + }); + + wrapper.find(actionMenuButton).simulate('click'); + + expect(wrapper.find(applyAlertTagsButton).first().exists()).toEqual(true); + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index a9e3958332322..df748803d47df 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -224,7 +224,6 @@ const AlertContextMenuComponent: React.FC { + const panelsToRender = [{ id: 0, items }, ...panels]; + return render( + {}} + button={<>} + > + + + ); +}; + +describe('useAlertTagsActions', () => { + beforeEach(() => { + (useAlertsPrivileges as jest.Mock).mockReturnValue({ + hasIndexWrite: true, + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should render alert tagging actions', () => { + const { result } = renderHook(() => useAlertTagsActions(defaultProps), { + wrapper: TestProviders, + }); + expect(result.current.alertTagsItems.length).toEqual(1); + expect(result.current.alertTagsPanels.length).toEqual(1); + + expect(result.current.alertTagsItems[0]['data-test-subj']).toEqual( + 'alert-tags-context-menu-item' + ); + expect(result.current.alertTagsPanels[0].content).toMatchInlineSnapshot(` + + `); + }); + + it("should not render alert tagging actions if user doesn't have write permissions", () => { + (useAlertsPrivileges as jest.Mock).mockReturnValue({ + hasIndexWrite: false, + }); + const { result } = renderHook(() => useAlertTagsActions(defaultProps), { + wrapper: TestProviders, + }); + expect(result.current.alertTagsItems.length).toEqual(0); + }); + + it('should still render if workflow_tags field does not exist', () => { + const newProps = { + ...defaultProps, + ecsRowData: { + _id: '123', + }, + }; + const { result } = renderHook(() => useAlertTagsActions(newProps), { + wrapper: TestProviders, + }); + expect(result.current.alertTagsItems.length).toEqual(1); + expect(result.current.alertTagsPanels.length).toEqual(1); + expect(result.current.alertTagsPanels[0].content).toMatchInlineSnapshot(` + + `); + }); + + it('should render the nested panel', async () => { + (useSetAlertTags as jest.Mock).mockReturnValue(jest.fn()); + (useUiSetting$ as jest.Mock).mockReturnValue([['default-test-tag-1', 'default-test-tag-2']]); + + const { result } = renderHook(() => useAlertTagsActions(defaultProps), { + wrapper: TestProviders, + }); + const alertTagsItems = result.current.alertTagsItems; + const alertTagsPanels = result.current.alertTagsPanels; + const { getByTestId } = renderContextMenu(alertTagsItems, alertTagsPanels); + + expect(getByTestId('alert-tags-selectable-menu')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alert_tags_actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alert_tags_actions.tsx index 46db4547b399f..16509b00c1f72 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alert_tags_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alert_tags_actions.tsx @@ -14,14 +14,17 @@ import { useBulkAlertTagsItems } from '../../../../common/components/toolbar/bul import { useAlertsPrivileges } from '../../../containers/detection_engine/alerts/use_alerts_privileges'; import type { AlertTableContextMenuItem } from '../types'; -interface Props { +export interface UseAlertTagsActionsProps { closePopover: () => void; ecsRowData: Ecs; - scopeId: string; refetch?: () => void; } -export const useAlertTagsActions = ({ closePopover, ecsRowData, scopeId, refetch }: Props) => { +export const useAlertTagsActions = ({ + closePopover, + ecsRowData, + refetch, +}: UseAlertTagsActionsProps) => { const { hasIndexWrite } = useAlertsPrivileges(); const alertId = ecsRowData._id; const alertTagData = useMemo(() => { @@ -40,7 +43,9 @@ export const useAlertTagsActions = ({ closePopover, ecsRowData, scopeId, refetch ]; }, [alertId, ecsRowData._index, ecsRowData?.kibana?.alert.workflow_tags]); - const { alertTagsItems, alertTagsPanels } = useBulkAlertTagsItems({ refetch }); + const { alertTagsItems, alertTagsPanels } = useBulkAlertTagsItems({ + refetch, + }); const itemsToReturn: AlertTableContextMenuItem[] = useMemo( () => diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx index 5874abe8397c5..b841ae0723eae 100644 --- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.test.tsx @@ -36,6 +36,7 @@ import { getUserPrivilegesMockDefaultValue } from '../../../common/components/us import { allCasesPermissions } from '../../../cases_test_utils'; import { HostStatus } from '../../../../common/endpoint/types'; import { ENDPOINT_CAPABILITIES } from '../../../../common/endpoint/service/response_actions/constants'; +import { ALERT_TAGS_CONTEXT_MENU_ITEM_TITLE } from '../../../common/components/toolbar/bulk_actions/translations'; jest.mock('../../../common/components/user_privileges'); @@ -240,6 +241,13 @@ describe('take action dropdown', () => { ).toEqual('Respond'); }); }); + test('should render "Apply alert tags"', async () => { + await waitFor(() => { + expect( + wrapper.find('[data-test-subj="alert-tags-context-menu-item"]').first().text() + ).toEqual(ALERT_TAGS_CONTEXT_MENU_ITEM_TITLE); + }); + }); }); describe('for Endpoint related actions', () => { diff --git a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx index 107af049ae6af..8a92032338940 100644 --- a/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/take_action_dropdown/index.tsx @@ -185,7 +185,6 @@ export const TakeActionDropdown = React.memo( const { alertTagsItems, alertTagsPanels } = useAlertTagsActions({ closePopover: closePopoverHandler, ecsRowData: ecsData ?? { _id: actionsData.eventId }, - scopeId, refetch, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/helpers.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/helpers.ts index ffa28ad832620..45bdadb2bc9e7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/helpers.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/helpers.ts @@ -8,11 +8,15 @@ import type { AlertTags } from '../../../../../common/detection_engine/schemas/common'; import * as i18n from './translations'; -export const validateAlertTagsArrays = (tags: AlertTags) => { +export const validateAlertTagsArrays = (tags: AlertTags, ids: string[]) => { + const validationErrors = []; + if (ids.length === 0) { + validationErrors.push(i18n.NO_IDS_VALIDATION_ERROR); + } const { tags_to_add: tagsToAdd, tags_to_remove: tagsToRemove } = tags; const duplicates = tagsToAdd.filter((tag) => tagsToRemove.includes(tag)); if (duplicates.length) { - return [i18n.ALERT_TAGS_VALIDATION_ERROR(JSON.stringify(duplicates))]; + validationErrors.push(i18n.ALERT_TAGS_VALIDATION_ERROR(JSON.stringify(duplicates))); } - return []; + return validationErrors; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.test.ts index b6476cd80e36d..70eeafe0ca71a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.test.ts @@ -27,12 +27,14 @@ describe('setAlertTagsRoute', () => { request = requestMock.create({ method: 'post', path: DETECTION_ENGINE_ALERT_TAGS_URL, - body: getSetAlertTagsRequestMock(['tag-1'], ['tag-2']), + body: getSetAlertTagsRequestMock(['tag-1'], ['tag-2'], ['test-id']), }); - context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockResponse( - getSuccessfulSignalUpdateResponse() - ); + context.core.elasticsearch.client.asCurrentUser.bulk.mockResponse({ + errors: false, + took: 0, + items: [{ update: { result: 'updated', status: 200, _index: 'test-index' } }], + }); const response = await server.inject(request, requestContextMock.convertContext(context)); @@ -45,7 +47,7 @@ describe('setAlertTagsRoute', () => { request = requestMock.create({ method: 'post', path: DETECTION_ENGINE_ALERT_TAGS_URL, - body: getSetAlertTagsRequestMock(['tag-1'], ['tag-1']), + body: getSetAlertTagsRequestMock(['tag-1'], ['tag-1'], ['test-id']), }); context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockResponse( @@ -65,20 +67,43 @@ describe('setAlertTagsRoute', () => { status_code: 400, }); }); - }); - describe('500s', () => { - test('returns 500 if ', async () => { + test('returns 400 if no alert ids are provided', async () => { request = requestMock.create({ method: 'post', path: DETECTION_ENGINE_ALERT_TAGS_URL, body: getSetAlertTagsRequestMock(['tag-1'], ['tag-2']), }); + context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockResponse( + getSuccessfulSignalUpdateResponse() + ); + + const response = await server.inject(request, requestContextMock.convertContext(context)); + context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockRejectedValue( new Error('Test error') ); + expect(response.body).toEqual({ + message: [`No alert ids were provided`], + status_code: 400, + }); + }); + }); + + describe('500s', () => { + test('returns 500 if asCurrentUser throws error', async () => { + request = requestMock.create({ + method: 'post', + path: DETECTION_ENGINE_ALERT_TAGS_URL, + body: getSetAlertTagsRequestMock(['tag-1'], ['tag-2'], ['test-id']), + }); + + context.core.elasticsearch.client.asCurrentUser.bulk.mockRejectedValue( + new Error('Test error') + ); + const response = await server.inject(request, requestContextMock.convertContext(context)); expect(response.body).toEqual({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts index 00e85bf29f598..20f9f53d4a673 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/set_alert_tags_route.ts @@ -32,13 +32,13 @@ export const setAlertTagsRoute = (router: SecuritySolutionPluginRouter) => { }, }, async (context, request, response) => { - const { tags, query } = request.body; + const { tags, ids } = request.body; const core = await context.core; const securitySolution = await context.securitySolution; const esClient = core.elasticsearch.client.asCurrentUser; const siemClient = securitySolution?.getAppClient(); const siemResponse = buildSiemResponse(response); - const validationErrors = validateAlertTagsArrays(tags); + const validationErrors = validateAlertTagsArrays(tags, ids); const spaceId = securitySolution?.getSpaceId() ?? 'default'; if (validationErrors.length) { @@ -49,45 +49,50 @@ export const setAlertTagsRoute = (router: SecuritySolutionPluginRouter) => { return siemResponse.error({ statusCode: 404 }); } - let queryObject; - if (query) { - queryObject = { - bool: { - filter: query, - }, - }; - } const tagsToAdd = uniq(tags.tags_to_add); const tagsToRemove = uniq(tags.tags_to_remove); - try { - const body = await esClient.updateByQuery({ - index: `${DEFAULT_ALERTS_INDEX}-${spaceId}`, - refresh: false, - body: { - script: { - params: { tagsToAdd, tagsToRemove }, - source: `List newTagsArray = []; - if (ctx._source["kibana.alert.workflow_tags"] != null) { - for (tag in ctx._source["kibana.alert.workflow_tags"]) { - if (!params.tagsToRemove.contains(tag)) { - newTagsArray.add(tag); - } - } - for (tag in params.tagsToAdd) { - if (!newTagsArray.contains(tag)) { - newTagsArray.add(tag) - } - } - ctx._source["kibana.alert.workflow_tags"] = newTagsArray; - } else { - ctx._source["kibana.alert.workflow_tags"] = params.tagsToAdd; - } - `, - lang: 'painless', + + const painlessScript = { + params: { tagsToAdd, tagsToRemove }, + source: `List newTagsArray = []; + if (ctx._source["kibana.alert.workflow_tags"] != null) { + for (tag in ctx._source["kibana.alert.workflow_tags"]) { + if (!params.tagsToRemove.contains(tag)) { + newTagsArray.add(tag); + } + } + for (tag in params.tagsToAdd) { + if (!newTagsArray.contains(tag)) { + newTagsArray.add(tag) + } + } + ctx._source["kibana.alert.workflow_tags"] = newTagsArray; + } else { + ctx._source["kibana.alert.workflow_tags"] = params.tagsToAdd; + } + `, + lang: 'painless', + }; + + const bulkUpdateRequest = []; + for (const id of ids) { + bulkUpdateRequest.push( + { + update: { + _index: `${DEFAULT_ALERTS_INDEX}-${spaceId}`, + _id: id, }, - query: queryObject, }, - ignore_unavailable: true, + { + script: painlessScript, + } + ); + } + + try { + const body = await esClient.bulk({ + refresh: 'wait_for', + body: bulkUpdateRequest, }); return response.ok({ body }); } catch (err) { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/translations.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/translations.ts index 74c662caa1cb5..715537fee47ab 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/translations.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/translations.ts @@ -13,3 +13,10 @@ export const ALERT_TAGS_VALIDATION_ERROR = (duplicates: string) => defaultMessage: 'Duplicate tags { duplicates } were found in the tags_to_add and tags_to_remove parameters.', }); + +export const NO_IDS_VALIDATION_ERROR = i18n.translate( + 'xpack.securitySolution.api.alertTags.noAlertIds', + { + defaultMessage: 'No alert ids were provided', + } +); diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index d1ab1f661a8c1..c3a06d41ba61d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -594,7 +594,7 @@ export interface BulkActionsConfig { interface PanelConfig { id: number; - title?: string; + title?: JSX.Element | string; 'data-test-subj'?: string; } diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts index 970d8b5426acd..1057b214736fe 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/set_alert_tags.ts @@ -24,9 +24,8 @@ import { getSignalsByIds, waitForRuleSuccess, getRuleForSignalTesting, - getAlertUpdateByQueryEmptyResponse, } from '../../utils'; -import { buildAlertTagsQuery, setAlertTags } from '../../utils/set_alert_tags'; +import { setAlertTags } from '../../utils/set_alert_tags'; // eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { @@ -37,24 +36,24 @@ export default ({ getService }: FtrProviderContext) => { describe('set_alert_tags', () => { describe('validation checks', () => { - it('should not give errors when querying and the signals index does not exist yet', async () => { + it('should give errors when no alert ids are provided', async () => { const { body } = await supertest .post(DETECTION_ENGINE_ALERT_TAGS_URL) .set('kbn-xsrf', 'true') - .send(setAlertTags({ tagsToAdd: [], tagsToRemove: [] })) - .expect(200); - - // remove any server generated items that are indeterministic - delete body.took; + .send(setAlertTags({ tagsToAdd: [], tagsToRemove: [], ids: [] })) + .expect(400); - expect(body).to.eql(getAlertUpdateByQueryEmptyResponse()); + expect(body).to.eql({ + message: ['No alert ids were provided'], + status_code: 400, + }); }); it('should give errors when duplicate tags exist in both tags_to_add and tags_to_remove', async () => { const { body } = await supertest .post(DETECTION_ENGINE_ALERT_TAGS_URL) .set('kbn-xsrf', 'true') - .send(setAlertTags({ tagsToAdd: ['test-1'], tagsToRemove: ['test-1'] })) + .send(setAlertTags({ tagsToAdd: ['test-1'], tagsToRemove: ['test-1'], ids: ['123'] })) .expect(400); expect(body).to.eql({ @@ -66,7 +65,7 @@ export default ({ getService }: FtrProviderContext) => { }); }); - describe.skip('tests with auditbeat data', () => { + describe('tests with auditbeat data', () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts'); }); @@ -102,7 +101,7 @@ export default ({ getService }: FtrProviderContext) => { setAlertTags({ tagsToAdd: ['tag-1'], tagsToRemove: [], - query: buildAlertTagsQuery(alertIds), + ids: alertIds, }) ) .expect(200); @@ -136,7 +135,7 @@ export default ({ getService }: FtrProviderContext) => { setAlertTags({ tagsToAdd: ['tag-1'], tagsToRemove: [], - query: buildAlertTagsQuery(alertIds.slice(0, 4)), + ids: alertIds.slice(0, 4), }) ) .expect(200); @@ -148,7 +147,7 @@ export default ({ getService }: FtrProviderContext) => { setAlertTags({ tagsToAdd: ['tag-1'], tagsToRemove: [], - query: buildAlertTagsQuery(alertIds), + ids: alertIds, }) ) .expect(200); @@ -182,7 +181,7 @@ export default ({ getService }: FtrProviderContext) => { setAlertTags({ tagsToAdd: ['tag-1', 'tag-2'], tagsToRemove: [], - query: buildAlertTagsQuery(alertIds), + ids: alertIds, }) ) .expect(200); @@ -194,7 +193,7 @@ export default ({ getService }: FtrProviderContext) => { setAlertTags({ tagsToAdd: [], tagsToRemove: ['tag-2'], - query: buildAlertTagsQuery(alertIds), + ids: alertIds, }) ) .expect(200); @@ -228,7 +227,7 @@ export default ({ getService }: FtrProviderContext) => { setAlertTags({ tagsToAdd: [], tagsToRemove: ['tag-1'], - query: buildAlertTagsQuery(alertIds), + ids: alertIds, }) ) .expect(200); diff --git a/x-pack/test/detection_engine_api_integration/utils/set_alert_tags.ts b/x-pack/test/detection_engine_api_integration/utils/set_alert_tags.ts index cff9524fbb337..5ba68ebf2fdba 100644 --- a/x-pack/test/detection_engine_api_integration/utils/set_alert_tags.ts +++ b/x-pack/test/detection_engine_api_integration/utils/set_alert_tags.ts @@ -5,31 +5,21 @@ * 2.0. */ -import { AlertTagQuery } from '@kbn/security-solution-plugin/common/detection_engine/schemas/common'; +import { AlertTagIds } from '@kbn/security-solution-plugin/common/detection_engine/schemas/common'; import { SetAlertTagsSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request/set_alert_tags_schema'; export const setAlertTags = ({ tagsToAdd, tagsToRemove, - query, + ids, }: { tagsToAdd: string[]; tagsToRemove: string[]; - query?: AlertTagQuery; + ids: AlertTagIds; }): SetAlertTagsSchema => ({ tags: { tags_to_add: tagsToAdd, tags_to_remove: tagsToRemove, }, - query, -}); - -export const buildAlertTagsQuery = (alertIds: string[]) => ({ - bool: { - filter: { - terms: { - _id: alertIds, - }, - }, - }, + ids, }); From a16f9482e35d4ab6ec0dfc7f0aad3a6c4153f709 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Tue, 11 Jul 2023 17:03:25 -0500 Subject: [PATCH 46/97] [Enterprise Search] rebrand ent-search breadcrumbs to Search (#161586) ## Summary Updated the enterprise-search base breadcrumbs to `Search` except for App Search & Workplace Search remain with Enterprise Search. Additionally fixed a small bug where the Vector Search breadcrumbs was Search > Vector Search > Vector Search ### Screenshots image image image --- .../generate_breadcrumbs.test.ts | 44 +++++++++++++++++++ .../kibana_chrome/generate_breadcrumbs.ts | 36 ++++++++++----- .../shared/kibana_chrome/set_chrome.test.tsx | 8 ++-- .../shared/kibana_chrome/set_chrome.tsx | 10 ++--- 4 files changed, 77 insertions(+), 21 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts index f5d10ba4bc00f..c767706fb0d6f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts @@ -20,6 +20,7 @@ import { useEuiBreadcrumbs, useEnterpriseSearchBreadcrumbs, useAppSearchBreadcrumbs, + useSearchBreadcrumbs, useWorkplaceSearchBreadcrumbs, } from './generate_breadcrumbs'; @@ -142,6 +143,49 @@ describe('useEuiBreadcrumbs', () => { }); }); +describe('useSearchBreadcrumbs', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('builds a chain of breadcrumbs with Search at the root', () => { + const breadcrumbs = [ + { + text: 'Page 1', + path: '/page1', + }, + { + text: 'Page 2', + path: '/page2', + }, + ]; + + expect(useSearchBreadcrumbs(breadcrumbs)).toEqual([ + { + text: 'Search', + href: '/app/enterprise_search/overview', + onClick: expect.any(Function), + }, + { + text: 'Page 1', + href: '/app/enterprise_search/page1', + onClick: expect.any(Function), + }, + { + text: 'Page 2', + }, + ]); + }); + + it('shows just the root if breadcrumbs is empty', () => { + expect(useSearchBreadcrumbs()).toEqual([ + { + text: 'Search', + }, + ]); + }); +}); + describe('useEnterpriseSearchBreadcrumbs', () => { beforeEach(() => { jest.clearAllMocks(); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts index a0e912fbae149..c340b070c35eb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts @@ -8,6 +8,7 @@ import { useValues } from 'kea'; import { EuiBreadcrumb } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { ANALYTICS_PLUGIN, @@ -17,6 +18,7 @@ import { ENTERPRISE_SEARCH_PRODUCT_NAME, ESRE_PLUGIN, SEARCH_EXPERIENCES_PLUGIN, + SEARCH_PRODUCT_NAME, VECTOR_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN, } from '../../../../common/constants'; @@ -100,6 +102,16 @@ export const useEuiBreadcrumbs = (breadcrumbs: Breadcrumbs): EuiBreadcrumb[] => * Product-specific breadcrumb helpers */ +export const useSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => + useEuiBreadcrumbs([ + { + text: SEARCH_PRODUCT_NAME, + path: ENTERPRISE_SEARCH_OVERVIEW_PLUGIN.URL, + shouldNotCreateHref: true, + }, + ...breadcrumbs, + ]); + export const useEnterpriseSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => useEuiBreadcrumbs([ { @@ -111,11 +123,16 @@ export const useEnterpriseSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => ]); export const useAnalyticsBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => - useEnterpriseSearchBreadcrumbs([{ text: ANALYTICS_PLUGIN.NAME, path: '/' }, ...breadcrumbs]); + useSearchBreadcrumbs([{ text: ANALYTICS_PLUGIN.NAME, path: '/' }, ...breadcrumbs]); export const useElasticsearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => - useEnterpriseSearchBreadcrumbs([ - { text: 'Getting started with Elasticsearch', path: '/' }, + useSearchBreadcrumbs([ + { + text: i18n.translate('xpack.enterpriseSearch.elasticsearch.breadcrumbs.title', { + defaultMessage: 'Getting started with Elasticsearch', + }), + path: '/', + }, ...breadcrumbs, ]); @@ -129,22 +146,19 @@ export const useWorkplaceSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => ]); export const useEnterpriseSearchContentBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => - useEnterpriseSearchBreadcrumbs([ + useSearchBreadcrumbs([ { text: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAV_TITLE, path: '/' }, ...breadcrumbs, ]); export const useSearchExperiencesBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => - useEnterpriseSearchBreadcrumbs([ - { text: SEARCH_EXPERIENCES_PLUGIN.NAV_TITLE, path: '/' }, - ...breadcrumbs, - ]); + useSearchBreadcrumbs([{ text: SEARCH_EXPERIENCES_PLUGIN.NAV_TITLE, path: '/' }, ...breadcrumbs]); export const useEnterpriseSearchApplicationsBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => - useEnterpriseSearchBreadcrumbs(breadcrumbs); + useSearchBreadcrumbs(breadcrumbs); export const useEsreBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => - useEnterpriseSearchBreadcrumbs([{ text: ESRE_PLUGIN.NAME, path: '/' }, ...breadcrumbs]); + useSearchBreadcrumbs([{ text: ESRE_PLUGIN.NAME, path: '/' }, ...breadcrumbs]); export const useVectorSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => - useEnterpriseSearchBreadcrumbs([{ text: VECTOR_SEARCH_PLUGIN.NAME, path: '/' }, ...breadcrumbs]); + useSearchBreadcrumbs([{ text: VECTOR_SEARCH_PLUGIN.NAV_TITLE, path: '/' }, ...breadcrumbs]); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx index aaf8e119e7c00..9fd2799c81330 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx @@ -15,12 +15,12 @@ import { shallow } from 'enzyme'; jest.mock('./generate_breadcrumbs', () => ({ useGenerateBreadcrumbs: jest.requireActual('./generate_breadcrumbs').useGenerateBreadcrumbs, - useEnterpriseSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), + useSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), useAppSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), useWorkplaceSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), })); import { - useEnterpriseSearchBreadcrumbs, + useSearchBreadcrumbs, useAppSearchBreadcrumbs, useWorkplaceSearchBreadcrumbs, } from './generate_breadcrumbs'; @@ -53,7 +53,7 @@ describe('Set Kibana Chrome helpers', () => { shallow(); expect(searchTitle).toHaveBeenCalledWith(['Hello World']); - expect(useEnterpriseSearchBreadcrumbs).toHaveBeenCalledWith([ + expect(useSearchBreadcrumbs).toHaveBeenCalledWith([ { text: 'Hello World', path: '/current-path', @@ -65,7 +65,7 @@ describe('Set Kibana Chrome helpers', () => { shallow(); expect(searchTitle).toHaveBeenCalledWith([]); - expect(useEnterpriseSearchBreadcrumbs).toHaveBeenCalledWith([]); + expect(useSearchBreadcrumbs).toHaveBeenCalledWith([]); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx index 3e7384bd2e593..2ea7e352ced6f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx @@ -9,13 +9,13 @@ import React, { useEffect } from 'react'; import { useValues } from 'kea'; -import { APPLICATIONS_PLUGIN, VECTOR_SEARCH_PLUGIN } from '../../../../common/constants'; +import { APPLICATIONS_PLUGIN } from '../../../../common/constants'; import { KibanaLogic } from '../kibana'; import { useGenerateBreadcrumbs, - useEnterpriseSearchBreadcrumbs, + useSearchBreadcrumbs, useEnterpriseSearchApplicationsBreadcrumbs, useAnalyticsBreadcrumbs, useEnterpriseSearchContentBreadcrumbs, @@ -64,7 +64,7 @@ export const SetSearchChrome: React.FC = ({ trail = [] }) => { const docTitle = searchTitle(title); const crumbs = useGenerateBreadcrumbs(trail); - const breadcrumbs = useEnterpriseSearchBreadcrumbs(crumbs); + const breadcrumbs = useSearchBreadcrumbs(crumbs); useEffect(() => { setBreadcrumbs(breadcrumbs); @@ -217,9 +217,7 @@ export const SetVectorSearchChrome: React.FC = ({ trail = [] }) const title = reverseArray(trail); const docTitle = vectorSearchTitle(title); - const breadcrumbs = useVectorSearchBreadcrumbs( - useGenerateBreadcrumbs([VECTOR_SEARCH_PLUGIN.NAV_TITLE, ...trail]) - ); + const breadcrumbs = useVectorSearchBreadcrumbs(useGenerateBreadcrumbs(trail)); useEffect(() => { setBreadcrumbs(breadcrumbs); From 06f7cbf9b6d3c63fea392d063c8b8f1dcd903199 Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Tue, 11 Jul 2023 17:44:08 -0600 Subject: [PATCH 47/97] [SLO] Add indicator to support histogram fields (#161582) ## Summary This PR add a new indicator to support histogram fields. This will allow you to either use a `range` aggregation or `value_count` aggregation for the good and total events; including support for filtering with KQL on both event types. When using a `range` aggregation, both the `from` and `to` thresholds are required for the range and events will be to total number of events within that range.[ Keep in mind, with the `range` aggregation, the range includes the `from` value and excludes the `to` value.](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-range-aggregation.html) This PR also includes support for using the histogram field for a "Custom Metric" indicator, `sum` is calculated on the values and not the counts. If you need it calculated on the counts then you have to use the histogram indicator. image --------- Co-authored-by: Kevin Delemme --- .../kbn-slo-schema/src/rest_specs/slo.ts | 3 + .../kbn-slo-schema/src/schema/indicators.ts | 45 ++ .../docs/openapi/slo/bundled.yaml | 112 +++- .../schemas/create_slo_request.yaml | 1 + .../indicator_properties_histogram.yaml | 92 ++++ .../slo/components/schemas/slo_response.yaml | 1 + .../schemas/update_slo_request.yaml | 1 + .../custom_kql_indicator_type_form.tsx | 19 +- .../custom_metric/custom_metric_type_form.tsx | 19 +- .../custom_metric/metric_indicator.tsx | 20 +- .../histogram/histogram_indicator.tsx | 296 +++++++++++ .../histogram_indicator_type_form.tsx | 152 ++++++ .../slo_edit_form_indicator_section.tsx | 3 + .../public/pages/slo_edit/constants.ts | 23 + .../pages/slo_edit/helpers/create_options.ts | 19 + .../hooks/use_section_form_validation.ts | 42 ++ .../slo_edit/hooks/use_unregister_fields.ts | 11 + .../slo_list_search_filter_sort_bar.tsx | 8 +- .../observability/public/utils/slo/labels.ts | 9 +- .../observability/server/routes/slo/route.ts | 2 + ...stogram_indicator_aggregation.test.ts.snap | 58 +++ ...et_histogram_indicator_aggregation.test.ts | 46 ++ .../get_histogram_indicator_aggregation.ts | 108 ++++ .../server/services/slo/aggregations/index.ts | 1 + .../server/services/slo/fixtures/slo.ts | 26 +- .../server/services/slo/get_preview_data.ts | 493 ++++++++++-------- .../__snapshots__/histogram.test.ts.snap | 317 +++++++++++ .../transform_generators/histogram.test.ts | 162 ++++++ .../slo/transform_generators/histogram.ts | 88 ++++ .../slo/transform_generators/index.ts | 1 + 30 files changed, 1908 insertions(+), 270 deletions(-) create mode 100644 x-pack/plugins/observability/docs/openapi/slo/components/schemas/indicator_properties_histogram.yaml create mode 100644 x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator.tsx create mode 100644 x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx create mode 100644 x-pack/plugins/observability/public/pages/slo_edit/helpers/create_options.ts create mode 100644 x-pack/plugins/observability/server/services/slo/aggregations/__snapshots__/get_histogram_indicator_aggregation.test.ts.snap create mode 100644 x-pack/plugins/observability/server/services/slo/aggregations/get_histogram_indicator_aggregation.test.ts create mode 100644 x-pack/plugins/observability/server/services/slo/aggregations/get_histogram_indicator_aggregation.ts create mode 100644 x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/histogram.test.ts.snap create mode 100644 x-pack/plugins/observability/server/services/slo/transform_generators/histogram.test.ts create mode 100644 x-pack/plugins/observability/server/services/slo/transform_generators/histogram.ts diff --git a/x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts b/x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts index 6ae5e852033a1..fda0e767c71d0 100644 --- a/x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts +++ b/x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts @@ -15,6 +15,7 @@ import { indicatorTypesSchema, kqlCustomIndicatorSchema, metricCustomIndicatorSchema, + histogramIndicatorSchema, objectiveSchema, optionalSettingsSchema, previewDataSchema, @@ -200,6 +201,7 @@ type Indicator = t.OutputOf; type APMTransactionErrorRateIndicator = t.OutputOf; type APMTransactionDurationIndicator = t.OutputOf; type MetricCustomIndicator = t.OutputOf; +type HistogramIndicator = t.OutputOf; type KQLCustomIndicator = t.OutputOf; export { @@ -247,6 +249,7 @@ export type { IndicatorType, Indicator, MetricCustomIndicator, + HistogramIndicator, KQLCustomIndicator, TimeWindow, }; diff --git a/x-pack/packages/kbn-slo-schema/src/schema/indicators.ts b/x-pack/packages/kbn-slo-schema/src/schema/indicators.ts index 8b46a1ed88b37..d24d26fbe51dc 100644 --- a/x-pack/packages/kbn-slo-schema/src/schema/indicators.ts +++ b/x-pack/packages/kbn-slo-schema/src/schema/indicators.ts @@ -85,6 +85,47 @@ const metricCustomIndicatorSchema = t.type({ }), }); +const rangeHistogramMetricType = t.literal('range'); +const rangeBasedHistogramMetricDef = t.intersection([ + t.type({ + field: t.string, + aggregation: rangeHistogramMetricType, + from: t.number, + to: t.number, + }), + t.partial({ + filter: t.string, + }), +]); + +const valueCountHistogramMetricType = t.literal('value_count'); +const valueCountBasedHistogramMetricDef = t.intersection([ + t.type({ + field: t.string, + aggregation: valueCountHistogramMetricType, + }), + t.partial({ + filter: t.string, + }), +]); + +const histogramMetricDef = t.union([ + valueCountBasedHistogramMetricDef, + rangeBasedHistogramMetricDef, +]); + +const histogramIndicatorTypeSchema = t.literal('sli.histogram.custom'); +const histogramIndicatorSchema = t.type({ + type: histogramIndicatorTypeSchema, + params: t.type({ + index: t.string, + timestampField: t.string, + filter: t.string, + good: histogramMetricDef, + total: histogramMetricDef, + }), +}); + const indicatorDataSchema = t.type({ dateRange: dateRangeSchema, good: t.number, @@ -96,6 +137,7 @@ const indicatorTypesSchema = t.union([ apmTransactionErrorRateIndicatorTypeSchema, kqlCustomIndicatorTypeSchema, metricCustomIndicatorTypeSchema, + histogramIndicatorTypeSchema, ]); // Validate that a string is a comma separated list of indicator types, @@ -122,6 +164,7 @@ const indicatorSchema = t.union([ apmTransactionErrorRateIndicatorSchema, kqlCustomIndicatorSchema, metricCustomIndicatorSchema, + histogramIndicatorSchema, ]); export { @@ -133,6 +176,8 @@ export { kqlCustomIndicatorTypeSchema, metricCustomIndicatorTypeSchema, metricCustomIndicatorSchema, + histogramIndicatorTypeSchema, + histogramIndicatorSchema, indicatorSchema, indicatorTypesArraySchema, indicatorTypesSchema, diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml index 533d06a67e54b..1c6954116076d 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml @@ -8,14 +8,17 @@ info: license: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license +servers: + - url: http://localhost:5601 + description: local +security: + - basicAuth: [] + - apiKeyAuth: [] tags: - name: slo description: SLO APIs enable you to define, manage and track service-level objectives - name: composite slo description: Composite SLO APIs enable you to define, manage and track a group of SLOs. -servers: - - url: http://localhost:5601 - description: local paths: /s/{spaceId}/api/observability/slos: post: @@ -697,6 +700,103 @@ components: description: The type of indicator. type: string example: sli.metric.custom + indicator_properties_histogram: + title: Histogram indicator + required: + - type + - params + description: Defines properties for a histogram indicator type + type: object + properties: + params: + description: An object containing the indicator parameters. + type: object + nullable: false + required: + - index + - timestampField + - good + - total + properties: + index: + description: The index or index pattern to use + type: string + example: my-service-* + filter: + description: the KQL query to filter the documents with. + type: string + example: 'field.environment : "production" and service.name : "my-service"' + timestampField: + description: | + The timestamp field used in the source indice. + type: string + example: timestamp + good: + description: | + An object defining the "good" events + type: object + required: + - aggregation + - field + properties: + field: + description: The field use to aggregate the good events. + type: string + example: processor.latency + aggregation: + description: The type of aggregation to use. + type: string + example: value_count + enum: + - value_count + - range + filter: + description: The filter for good events. + type: string + example: 'processor.outcome: "success"' + from: + description: The starting value of the range. Only required for "range" aggregations. + type: number + example: 0 + to: + description: The ending value of the range. Only required for "range" aggregations. + type: number + example: 100 + total: + description: | + An object defining the "total" events + type: object + required: + - aggregation + - field + properties: + field: + description: The field use to aggregate the good events. + type: string + example: processor.latency + aggregation: + description: The type of aggregation to use. + type: string + example: value_count + enum: + - value_count + - range + filter: + description: The filter for total events. + type: string + example: 'processor.outcome : *' + from: + description: The starting value of the range. Only required for "range" aggregations. + type: number + example: 0 + to: + description: The ending value of the range. Only required for "range" aggregations. + type: number + example: 100 + type: + description: The type of indicator. + type: string + example: sli.histogram.custom time_window: title: Time window required: @@ -816,6 +916,7 @@ components: - $ref: '#/components/schemas/indicator_properties_apm_availability' - $ref: '#/components/schemas/indicator_properties_apm_latency' - $ref: '#/components/schemas/indicator_properties_custom_metric' + - $ref: '#/components/schemas/indicator_properties_histogram' timeWindow: $ref: '#/components/schemas/time_window' budgetingMethod: @@ -958,6 +1059,7 @@ components: - $ref: '#/components/schemas/indicator_properties_apm_availability' - $ref: '#/components/schemas/indicator_properties_apm_latency' - $ref: '#/components/schemas/indicator_properties_custom_metric' + - $ref: '#/components/schemas/indicator_properties_histogram' timeWindow: $ref: '#/components/schemas/time_window' budgetingMethod: @@ -1010,6 +1112,7 @@ components: - $ref: '#/components/schemas/indicator_properties_apm_availability' - $ref: '#/components/schemas/indicator_properties_apm_latency' - $ref: '#/components/schemas/indicator_properties_custom_metric' + - $ref: '#/components/schemas/indicator_properties_histogram' timeWindow: $ref: '#/components/schemas/time_window' budgetingMethod: @@ -1054,6 +1157,3 @@ components: example: 0.9836 errorBudget: $ref: '#/components/schemas/error_budget' -security: - - basicAuth: [] - - apiKeyAuth: [] diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_slo_request.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_slo_request.yaml index 86394ff6f210c..eb790b17e0d29 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_slo_request.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/create_slo_request.yaml @@ -26,6 +26,7 @@ properties: - $ref: "indicator_properties_apm_availability.yaml" - $ref: "indicator_properties_apm_latency.yaml" - $ref: "indicator_properties_custom_metric.yaml" + - $ref: 'indicator_properties_histogram.yaml' timeWindow: $ref: "time_window.yaml" budgetingMethod: diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/indicator_properties_histogram.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/indicator_properties_histogram.yaml new file mode 100644 index 0000000000000..dc39a3599a7b2 --- /dev/null +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/indicator_properties_histogram.yaml @@ -0,0 +1,92 @@ +title: Histogram indicator +required: + - type + - params +description: Defines properties for a histogram indicator type +type: object +properties: + params: + description: An object containing the indicator parameters. + type: object + nullable: false + required: + - index + - timestampField + - good + - total + properties: + index: + description: The index or index pattern to use + type: string + example: my-service-* + filter: + description: the KQL query to filter the documents with. + type: string + example: 'field.environment : "production" and service.name : "my-service"' + timestampField: + description: > + The timestamp field used in the source indice. + type: string + example: timestamp + good: + description: > + An object defining the "good" events + type: object + required: + - aggregation + - field + properties: + field: + description: The field use to aggregate the good events. + type: string + example: processor.latency + aggregation: + description: The type of aggregation to use. + type: string + example: value_count + enum: [value_count, range] + filter: + description: The filter for good events. + type: string + example: "processor.outcome: \"success\"" + from: + description: The starting value of the range. Only required for "range" aggregations. + type: number + example: 0 + to: + description: The ending value of the range. Only required for "range" aggregations. + type: number + example: 100 + total: + description: > + An object defining the "total" events + type: object + required: + - aggregation + - field + properties: + field: + description: The field use to aggregate the good events. + type: string + example: processor.latency + aggregation: + description: The type of aggregation to use. + type: string + example: value_count + enum: [value_count, range] + filter: + description: The filter for total events. + type: string + example: "processor.outcome : *" + from: + description: The starting value of the range. Only required for "range" aggregations. + type: number + example: 0 + to: + description: The ending value of the range. Only required for "range" aggregations. + type: number + example: 100 + type: + description: The type of indicator. + type: string + example: sli.histogram.custom diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml index afe03d12d676f..112191e55654b 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/slo_response.yaml @@ -19,6 +19,7 @@ properties: - $ref: "indicator_properties_apm_availability.yaml" - $ref: "indicator_properties_apm_latency.yaml" - $ref: "indicator_properties_custom_metric.yaml" + - $ref: "indicator_properties_histogram.yaml" timeWindow: $ref: "time_window.yaml" budgetingMethod: diff --git a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_slo_request.yaml b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_slo_request.yaml index 0587ddf0abb2b..0ba9a79ac2ac1 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_slo_request.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/components/schemas/update_slo_request.yaml @@ -16,6 +16,7 @@ properties: - $ref: "indicator_properties_apm_availability.yaml" - $ref: "indicator_properties_apm_latency.yaml" - $ref: "indicator_properties_custom_metric.yaml" + - $ref: "indicator_properties_histogram.yaml" timeWindow: $ref: "time_window.yaml" budgetingMethod: diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx index 57786d21fe3f6..c07ce5d132489 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx @@ -16,20 +16,13 @@ import { import { i18n } from '@kbn/i18n'; import React from 'react'; import { Controller, useFormContext } from 'react-hook-form'; -import { - Field, - useFetchIndexPatternFields, -} from '../../../../hooks/slo/use_fetch_index_pattern_fields'; +import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields'; +import { createOptionsFromFields } from '../../helpers/create_options'; import { CreateSLOForm } from '../../types'; import { DataPreviewChart } from '../common/data_preview_chart'; import { QueryBuilder } from '../common/query_builder'; import { IndexSelection } from '../custom_common/index_selection'; -interface Option { - label: string; - value: string; -} - export function CustomKqlIndicatorTypeForm() { const { control, watch, getFieldState } = useFormContext(); @@ -80,7 +73,7 @@ export function CustomKqlIndicatorTypeForm() { field.onChange(''); }} - options={createOptions(timestampFields)} + options={createOptionsFromFields(timestampFields)} selectedOptions={ !!index && !!field.value && @@ -186,9 +179,3 @@ export function CustomKqlIndicatorTypeForm() { ); } - -function createOptions(fields: Field[]): Option[] { - return fields - .map((field) => ({ label: field.name, value: field.name })) - .sort((a, b) => String(a.label).localeCompare(b.label)); -} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx index 7e3a90f189ccc..74a2a8d701adf 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx @@ -17,10 +17,8 @@ import { import { i18n } from '@kbn/i18n'; import React from 'react'; import { Controller, useFormContext } from 'react-hook-form'; -import { - Field, - useFetchIndexPatternFields, -} from '../../../../hooks/slo/use_fetch_index_pattern_fields'; +import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields'; +import { createOptionsFromFields } from '../../helpers/create_options'; import { CreateSLOForm } from '../../types'; import { DataPreviewChart } from '../common/data_preview_chart'; import { QueryBuilder } from '../common/query_builder'; @@ -29,11 +27,6 @@ import { MetricIndicator } from './metric_indicator'; export { NEW_CUSTOM_METRIC } from './metric_indicator'; -interface Option { - label: string; - value: string; -} - export function CustomMetricIndicatorTypeForm() { const { control, watch, getFieldState } = useFormContext(); @@ -85,7 +78,7 @@ export function CustomMetricIndicatorTypeForm() { field.onChange(''); }} - options={createOptions(timestampFields)} + options={createOptionsFromFields(timestampFields)} selectedOptions={ !!watch('indicator.params.index') && !!field.value && @@ -226,9 +219,3 @@ export function CustomMetricIndicatorTypeForm() { ); } - -function createOptions(fields: Field[]): Option[] { - return fields - .map((field) => ({ label: field.name, value: field.name })) - .sort((a, b) => String(a.label).localeCompare(b.label)); -} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/metric_indicator.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/metric_indicator.tsx index f6968436a15e9..cc6f935256516 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/metric_indicator.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/metric_indicator.tsx @@ -22,14 +22,10 @@ import { first, range, xor } from 'lodash'; import React, { ReactNode } from 'react'; import { Controller, useFieldArray, useFormContext } from 'react-hook-form'; import { Field } from '../../../../hooks/slo/use_fetch_index_pattern_fields'; +import { createOptionsFromFields } from '../../helpers/create_options'; import { CreateSLOForm } from '../../types'; import { QueryBuilder } from '../common/query_builder'; -interface Option { - label: string; - value: string; -} - interface MetricIndicatorProps { type: 'good' | 'total'; indexFields: Field[] | undefined; @@ -52,16 +48,12 @@ const validateEquation = (value: string) => { return result === null; }; -function createOptions(fields: Field[]): Option[] { - return fields - .map((field) => ({ label: field.name, value: field.name })) - .sort((a, b) => String(a.label).localeCompare(b.label)); -} - function createEquationFromMetric(names: string[]) { return names.join(' + '); } +const SUPPORTED_FIELD_TYPES = ['number', 'histogram']; + export function MetricIndicator({ type, indexFields, @@ -73,7 +65,9 @@ export function MetricIndicator({ equationTooltip, }: MetricIndicatorProps) { const { control, watch, setValue, register } = useFormContext(); - const metricFields = (indexFields ?? []).filter((field) => field.type === 'number'); + const metricFields = (indexFields ?? []).filter((field) => + SUPPORTED_FIELD_TYPES.includes(field.type) + ); const { fields, append, remove } = useFieldArray({ control, @@ -166,7 +160,7 @@ export function MetricIndicator({ ] : [] } - options={createOptions(metricFields)} + options={createOptionsFromFields(metricFields)} /> )} /> diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator.tsx new file mode 100644 index 0000000000000..fd242dafde115 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator.tsx @@ -0,0 +1,296 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Fragment } from 'react'; +import { Controller, useFormContext } from 'react-hook-form'; +import { i18n } from '@kbn/i18n'; +import { + EuiComboBox, + EuiComboBoxOptionOption, + EuiFieldNumber, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiIconTip, + EuiSpacer, +} from '@elastic/eui'; +import { CreateSLOForm } from '../../types'; +import { QueryBuilder } from '../common/query_builder'; +import { Field } from '../../../../hooks/slo/use_fetch_index_pattern_fields'; +import { createOptionsFromFields } from '../../helpers/create_options'; + +interface HistogramIndicatorProps { + type: 'good' | 'total'; + indexFields: Field[] | undefined; + isLoadingIndex: boolean; +} + +const AGGREGATIONS = { + value_count: { + value: 'value_count', + label: i18n.translate('xpack.observability.slo.sloEdit.sliType.histogram.valueCountLabel', { + defaultMessage: 'Value count', + }), + }, + range: { + value: 'range', + label: i18n.translate('xpack.observability.slo.sloEdit.sliType.histogram.rangeLabel', { + defaultMessage: 'Range', + }), + }, +}; + +const AGGREGATION_OPTIONS = Object.values(AGGREGATIONS); + +export function HistogramIndicator({ type, indexFields, isLoadingIndex }: HistogramIndicatorProps) { + const { control, watch } = useFormContext(); + + const histogramFields = (indexFields ?? []).filter((field) => field.type === 'histogram'); + const indexPattern = watch('indicator.params.index'); + const aggregation = watch(`indicator.params.${type}.aggregation`); + + const aggregationTooltip = ( + + ); + + const fromTooltip = ( + + ); + + const toTooltip = ( + + ); + + const aggregationLabel = i18n.translate( + 'xpack.observability.slo.sloEdit.sliType.histogram.aggregationLabel', + { defaultMessage: 'Aggregation' } + ); + + const metricLabel = i18n.translate( + 'xpack.observability.slo.sloEdit.sliType.histogram.metricLabel', + { defaultMessage: 'Field' } + ); + + const toLabel = i18n.translate('xpack.observability.slo.sloEdit.sliType.histogram.toLabel', { + defaultMessage: 'To', + }); + + const fromLabel = i18n.translate('xpack.observability.slo.sloEdit.sliType.histogram.fromLabel', { + defaultMessage: 'From', + }); + + return ( + + + + + {aggregationLabel} {aggregationTooltip} + + } + > + ( + { + if (selected.length) { + return field.onChange(selected[0].value); + } + field.onChange(''); + }} + selectedOptions={!!field.value ? [AGGREGATIONS[field.value]] : []} + options={AGGREGATION_OPTIONS} + /> + )} + /> + + + + {metricLabel}}> + ( + { + if (selected.length) { + return field.onChange(selected[0].value); + } + field.onChange(''); + }} + selectedOptions={ + !!indexPattern && + !!field.value && + histogramFields.some((histoField) => histoField.name === field.value) + ? [ + { + value: field.value, + label: field.value, + }, + ] + : [] + } + options={createOptionsFromFields(histogramFields)} + /> + )} + /> + + + + + + {aggregation === 'range' && ( + + + + + {fromLabel} {fromTooltip} + + } + > + ( + field.onChange(Number(event.target.value))} + /> + )} + /> + + + + + {toLabel} {toTooltip} + + } + > + ( + field.onChange(Number(event.target.value))} + /> + )} + /> + + + + + )} + + + } + /> + + + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx new file mode 100644 index 0000000000000..36601b4a072db --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx @@ -0,0 +1,152 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiComboBox, + EuiComboBoxOptionOption, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiIconTip, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { Controller, useFormContext } from 'react-hook-form'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields'; +import { createOptionsFromFields } from '../../helpers/create_options'; +import { CreateSLOForm } from '../../types'; +import { DataPreviewChart } from '../common/data_preview_chart'; +import { QueryBuilder } from '../common/query_builder'; +import { IndexSelection } from '../custom_common/index_selection'; +import { HistogramIndicator } from './histogram_indicator'; + +export function HistogramIndicatorTypeForm() { + const { control, watch, getFieldState } = useFormContext(); + + const index = watch('indicator.params.index'); + const { isLoading, data: indexFields } = useFetchIndexPatternFields(index); + const timestampFields = (indexFields ?? []).filter((field) => field.type === 'date'); + + return ( + + + + + + + + ( + { + if (selected.length) { + return field.onChange(selected[0].value); + } + + field.onChange(''); + }} + options={createOptionsFromFields(timestampFields)} + selectedOptions={ + !!index && + !!field.value && + timestampFields.some((timestampField) => timestampField.name === field.value) + ? [{ value: field.value, label: field.value }] + : [] + } + singleSelection={{ asPlainText: true }} + /> + )} + /> + + + + + + + } + /> + + + + +

+ +

+
+ + +
+ + + +

+ +

+
+ + +
+ + +
+ ); +} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form_indicator_section.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form_indicator_section.tsx index 75d0829d8b3d3..1be3a5b10e537 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form_indicator_section.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form_indicator_section.tsx @@ -16,6 +16,7 @@ import { ApmAvailabilityIndicatorTypeForm } from './apm_availability/apm_availab import { ApmLatencyIndicatorTypeForm } from './apm_latency/apm_latency_indicator_type_form'; import { CustomKqlIndicatorTypeForm } from './custom_kql/custom_kql_indicator_type_form'; import { CustomMetricIndicatorTypeForm } from './custom_metric/custom_metric_type_form'; +import { HistogramIndicatorTypeForm } from './histogram/histogram_indicator_type_form'; import { maxWidth } from './slo_edit_form'; interface SloEditFormIndicatorSectionProps { @@ -36,6 +37,8 @@ export function SloEditFormIndicatorSection({ isEditMode }: SloEditFormIndicator return ; case 'sli.metric.custom': return ; + case 'sli.histogram.custom': + return ; default: return null; } diff --git a/x-pack/plugins/observability/public/pages/slo_edit/constants.ts b/x-pack/plugins/observability/public/pages/slo_edit/constants.ts index 207573f0c6036..8d76c7241e6a0 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/constants.ts +++ b/x-pack/plugins/observability/public/pages/slo_edit/constants.ts @@ -10,6 +10,7 @@ import { APMTransactionDurationIndicator, APMTransactionErrorRateIndicator, BudgetingMethod, + HistogramIndicator, IndicatorType, KQLCustomIndicator, MetricCustomIndicator, @@ -22,6 +23,7 @@ import { INDICATOR_APM_LATENCY, INDICATOR_CUSTOM_KQL, INDICATOR_CUSTOM_METRIC, + INDICATOR_HISTOGRAM, } from '../../utils/slo/labels'; import { CreateSLOForm } from './types'; @@ -37,6 +39,10 @@ export const SLI_OPTIONS: Array<{ value: 'sli.metric.custom', text: INDICATOR_CUSTOM_METRIC, }, + { + value: 'sli.histogram.custom', + text: INDICATOR_HISTOGRAM, + }, { value: 'sli.apm.transactionDuration', text: INDICATOR_APM_LATENCY, @@ -118,6 +124,23 @@ export const CUSTOM_METRIC_DEFAULT_VALUES: MetricCustomIndicator = { }, }; +export const HISTOGRAM_DEFAULT_VALUES: HistogramIndicator = { + type: 'sli.histogram.custom' as const, + params: { + index: '', + timestampField: '', + filter: '', + good: { + field: '', + aggregation: 'value_count' as const, + }, + total: { + field: '', + aggregation: 'value_count' as const, + }, + }, +}; + export const APM_LATENCY_DEFAULT_VALUES: APMTransactionDurationIndicator = { type: 'sli.apm.transactionDuration' as const, params: { diff --git a/x-pack/plugins/observability/public/pages/slo_edit/helpers/create_options.ts b/x-pack/plugins/observability/public/pages/slo_edit/helpers/create_options.ts new file mode 100644 index 0000000000000..c76b881ccc8aa --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slo_edit/helpers/create_options.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Field } from '../../../hooks/slo/use_fetch_index_pattern_fields'; + +interface Option { + label: string; + value: string; +} + +export function createOptionsFromFields(fields: Field[]): Option[] { + return fields + .map((field) => ({ label: field.name, value: field.name })) + .sort((a, b) => String(a.label).localeCompare(b.label)); +} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_section_form_validation.ts b/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_section_form_validation.ts index e72c3ed0ceff8..e0c2652bfc46d 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_section_form_validation.ts +++ b/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_section_form_validation.ts @@ -54,6 +54,48 @@ export function useSectionFormValidation({ getFieldState, getValues, formState, isGoodParamsValid() && isTotalParamsValid(); break; + case 'sli.histogram.custom': + const isRangeValid = (type: 'good' | 'total') => { + const aggregation = getValues(`indicator.params.${type}.aggregation`); + // If aggreagtion is a value count we can exit early with true + if (aggregation === 'value_count') { + return true; + } + const from = getValues(`indicator.params.${type}.from`); + const to = getValues(`indicator.params.${type}.to`); + // If both from and to are defined and from is less that to, return true + if (from != null && to != null && from < to) { + return true; + } + return false; + }; + isIndicatorSectionValid = + ( + [ + 'indicator.params.index', + 'indicator.params.filter', + 'indicator.params.timestampField', + 'indicator.params.good.aggregation', + 'indicator.params.total.aggregation', + 'indicator.params.good.field', + 'indicator.params.total.field', + 'indicator.params.good.filter', + 'indicator.params.total.filter', + ] as const + ).every((field) => !getFieldState(field).invalid) && + ( + [ + 'indicator.params.good.aggregation', + 'indicator.params.total.aggregation', + 'indicator.params.good.field', + 'indicator.params.total.field', + 'indicator.params.index', + 'indicator.params.timestampField', + ] as const + ).every((field) => !!getValues(field)) && + isRangeValid('good') && + isRangeValid('total'); + break; case 'sli.kql.custom': isIndicatorSectionValid = ( diff --git a/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_unregister_fields.ts b/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_unregister_fields.ts index de7a926bb896b..973a023bdae77 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_unregister_fields.ts +++ b/x-pack/plugins/observability/public/pages/slo_edit/hooks/use_unregister_fields.ts @@ -16,6 +16,7 @@ import { APM_LATENCY_DEFAULT_VALUES, CUSTOM_KQL_DEFAULT_VALUES, CUSTOM_METRIC_DEFAULT_VALUES, + HISTOGRAM_DEFAULT_VALUES, SLO_EDIT_FORM_DEFAULT_VALUES, } from '../constants'; import { CreateSLOForm } from '../types'; @@ -58,6 +59,16 @@ export function useUnregisterFields({ isEditMode }: { isEditMode: boolean }) { } ); break; + case 'sli.histogram.custom': + reset( + Object.assign({}, SLO_EDIT_FORM_DEFAULT_VALUES, { + indicator: HISTOGRAM_DEFAULT_VALUES, + }), + { + keepDefaultValues: true, + } + ); + break; case 'sli.apm.transactionDuration': reset( Object.assign({}, SLO_EDIT_FORM_DEFAULT_VALUES, { diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_list_search_filter_sort_bar.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_list_search_filter_sort_bar.tsx index ab81a58ad40be..89bc65a8da8e5 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_list_search_filter_sort_bar.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_list_search_filter_sort_bar.tsx @@ -24,6 +24,7 @@ import { INDICATOR_APM_LATENCY, INDICATOR_CUSTOM_KQL, INDICATOR_CUSTOM_METRIC, + INDICATOR_HISTOGRAM, } from '../../../utils/slo/labels'; export interface SloListSearchFilterSortBarProps { @@ -38,7 +39,8 @@ export type FilterType = | 'sli.apm.transactionDuration' | 'sli.apm.transactionErrorRate' | 'sli.kql.custom' - | 'sli.metric.custom'; + | 'sli.metric.custom' + | 'sli.histogram.custom'; export type Item = EuiSelectableOption & { label: string; @@ -79,6 +81,10 @@ const INDICATOR_TYPE_OPTIONS: Array> = [ label: INDICATOR_CUSTOM_METRIC, type: 'sli.metric.custom', }, + { + label: INDICATOR_HISTOGRAM, + type: 'sli.histogram.custom', + }, ]; export function SloListSearchFilterSortBar({ diff --git a/x-pack/plugins/observability/public/utils/slo/labels.ts b/x-pack/plugins/observability/public/utils/slo/labels.ts index 6df6b0520c9e0..43384539f2a84 100644 --- a/x-pack/plugins/observability/public/utils/slo/labels.ts +++ b/x-pack/plugins/observability/public/utils/slo/labels.ts @@ -21,6 +21,10 @@ export const INDICATOR_CUSTOM_METRIC = i18n.translate( } ); +export const INDICATOR_HISTOGRAM = i18n.translate('xpack.observability.slo.indicators.histogram', { + defaultMessage: 'Histogram Metric', +}); + export const INDICATOR_APM_LATENCY = i18n.translate( 'xpack.observability.slo.indicators.apmLatency', { defaultMessage: 'APM latency' } @@ -47,8 +51,11 @@ export function toIndicatorTypeLabel( case 'sli.metric.custom': return INDICATOR_CUSTOM_METRIC; + case 'sli.histogram.custom': + return INDICATOR_HISTOGRAM; + default: - assertNever(indicatorType); + assertNever(indicatorType as never); } } diff --git a/x-pack/plugins/observability/server/routes/slo/route.ts b/x-pack/plugins/observability/server/routes/slo/route.ts index f41d37d4fc573..c98a1579d2042 100644 --- a/x-pack/plugins/observability/server/routes/slo/route.ts +++ b/x-pack/plugins/observability/server/routes/slo/route.ts @@ -32,6 +32,7 @@ import { import { ApmTransactionDurationTransformGenerator, ApmTransactionErrorRateTransformGenerator, + HistogramTransformGenerator, KQLCustomTransformGenerator, MetricCustomTransformGenerator, TransformGenerator, @@ -51,6 +52,7 @@ const transformGenerators: Record = { 'sli.apm.transactionErrorRate': new ApmTransactionErrorRateTransformGenerator(), 'sli.kql.custom': new KQLCustomTransformGenerator(), 'sli.metric.custom': new MetricCustomTransformGenerator(), + 'sli.histogram.custom': new HistogramTransformGenerator(), }; const isLicenseAtLeastPlatinum = async (context: ObservabilityRequestHandlerContext) => { diff --git a/x-pack/plugins/observability/server/services/slo/aggregations/__snapshots__/get_histogram_indicator_aggregation.test.ts.snap b/x-pack/plugins/observability/server/services/slo/aggregations/__snapshots__/get_histogram_indicator_aggregation.test.ts.snap new file mode 100644 index 0000000000000..dac0d8cebfdd7 --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/aggregations/__snapshots__/get_histogram_indicator_aggregation.test.ts.snap @@ -0,0 +1,58 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`GetHistogramIndicatorAggregation should generate a aggregation for good events 1`] = ` +Object { + "_good": Object { + "aggs": Object { + "total": Object { + "range": Object { + "field": "latency", + "keyed": true, + "ranges": Array [ + Object { + "from": 0, + "to": 100, + }, + ], + }, + }, + }, + "filter": Object { + "match_all": Object {}, + }, + }, + "goodEvents": Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_good>total['0.0-100.0']>_count", + }, + "script": "params.value", + }, + }, +} +`; + +exports[`GetHistogramIndicatorAggregation should generate a aggregation for total events 1`] = ` +Object { + "_total": Object { + "aggs": Object { + "total": Object { + "value_count": Object { + "field": "latency", + }, + }, + }, + "filter": Object { + "match_all": Object {}, + }, + }, + "totalEvents": Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_total>total", + }, + "script": "params.value", + }, + }, +} +`; diff --git a/x-pack/plugins/observability/server/services/slo/aggregations/get_histogram_indicator_aggregation.test.ts b/x-pack/plugins/observability/server/services/slo/aggregations/get_histogram_indicator_aggregation.test.ts new file mode 100644 index 0000000000000..74ae690e848bb --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/aggregations/get_histogram_indicator_aggregation.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createHistogramIndicator } from '../fixtures/slo'; +import { GetHistogramIndicatorAggregation } from './get_histogram_indicator_aggregation'; + +describe('GetHistogramIndicatorAggregation', () => { + it('should generate a aggregation for good events', () => { + const getHistogramIndicatorAggregations = new GetHistogramIndicatorAggregation( + createHistogramIndicator() + ); + expect( + getHistogramIndicatorAggregations.execute({ type: 'good', aggregationKey: 'goodEvents' }) + ).toMatchSnapshot(); + }); + + it('should generate a aggregation for total events', () => { + const getHistogramIndicatorAggregations = new GetHistogramIndicatorAggregation( + createHistogramIndicator() + ); + expect( + getHistogramIndicatorAggregations.execute({ type: 'total', aggregationKey: 'totalEvents' }) + ).toMatchSnapshot(); + }); + + it('should throw and error when the "from" is greater than "to"', () => { + const getHistogramIndicatorAggregations = new GetHistogramIndicatorAggregation( + createHistogramIndicator({ + good: { + field: 'latency', + aggregation: 'range', + from: 100, + to: 0, + filter: '', + }, + }) + ); + expect(() => + getHistogramIndicatorAggregations.execute({ type: 'good', aggregationKey: 'goodEvents' }) + ).toThrow('Invalid Range: "from" should be less that "to".'); + }); +}); diff --git a/x-pack/plugins/observability/server/services/slo/aggregations/get_histogram_indicator_aggregation.ts b/x-pack/plugins/observability/server/services/slo/aggregations/get_histogram_indicator_aggregation.ts new file mode 100644 index 0000000000000..2f195d7a0a150 --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/aggregations/get_histogram_indicator_aggregation.ts @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { HistogramIndicator } from '@kbn/slo-schema'; +import { getElastichsearchQueryOrThrow } from '../transform_generators/common'; + +type HistogramIndicatorDef = + | HistogramIndicator['params']['good'] + | HistogramIndicator['params']['total']; + +export class GetHistogramIndicatorAggregation { + constructor(private indicator: HistogramIndicator) {} + + private buildAggregation(type: 'good' | 'total', indicator: HistogramIndicatorDef) { + const filter = indicator.filter + ? getElastichsearchQueryOrThrow(indicator.filter) + : { match_all: {} }; + if (indicator.aggregation === 'value_count') { + return { + filter, + aggs: { + total: { + value_count: { field: indicator.field }, + }, + }, + }; + } + + if (indicator.aggregation === 'range' && (indicator.from == null || indicator.to == null)) { + throw new Error('Invalid Range: both "from" or "to" are required for a range aggregation.'); + } + + if ( + indicator.aggregation === 'range' && + indicator.from != null && + indicator.to != null && + indicator.from >= indicator.to + ) { + throw new Error('Invalid Range: "from" should be less that "to".'); + } + + const range: { from?: number; to?: number } = {}; + if (indicator.from != null) { + range.from = indicator.from; + } + + if (indicator.to != null) { + range.to = indicator.to; + } + + return { + filter, + aggs: { + total: { + range: { + field: indicator.field, + keyed: true, + ranges: [range], + }, + }, + }, + }; + } + + private formatNumberAsFloatString(value: number) { + return value % 1 === 0 ? `${value}.0` : `${value}`; + } + + private buildRangeKey(from: number | undefined, to: number | undefined) { + const fromString = from != null ? this.formatNumberAsFloatString(from) : '*'; + const toString = to != null ? this.formatNumberAsFloatString(to) : '*'; + return `${fromString}-${toString}`; + } + + private buildBucketScript(type: 'good' | 'total', indicator: HistogramIndicatorDef) { + if (indicator.aggregation === 'value_count') { + return { + bucket_script: { + buckets_path: { + value: `_${type}>total`, + }, + script: 'params.value', + }, + }; + } + const rangeKey = this.buildRangeKey(indicator.from, indicator.to); + return { + bucket_script: { + buckets_path: { + value: `_${type}>total['${rangeKey}']>_count`, + }, + script: 'params.value', + }, + }; + } + + public execute({ type, aggregationKey }: { type: 'good' | 'total'; aggregationKey: string }) { + const indicatorDef = this.indicator.params[type]; + return { + [`_${type}`]: this.buildAggregation(type, indicatorDef), + [aggregationKey]: this.buildBucketScript(type, indicatorDef), + }; + } +} diff --git a/x-pack/plugins/observability/server/services/slo/aggregations/index.ts b/x-pack/plugins/observability/server/services/slo/aggregations/index.ts index 49e918545ad89..b814152a4fcd5 100644 --- a/x-pack/plugins/observability/server/services/slo/aggregations/index.ts +++ b/x-pack/plugins/observability/server/services/slo/aggregations/index.ts @@ -5,4 +5,5 @@ * 2.0. */ +export * from './get_histogram_indicator_aggregation'; export * from './get_custom_metric_indicator_aggregation'; diff --git a/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts b/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts index cf543adaa29b5..fc7cf292095c9 100644 --- a/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts +++ b/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts @@ -8,7 +8,7 @@ import { cloneDeep } from 'lodash'; import { v1 as uuidv1 } from 'uuid'; import { SavedObject } from '@kbn/core-saved-objects-server'; -import { sloSchema, CreateSLOParams } from '@kbn/slo-schema'; +import { sloSchema, CreateSLOParams, HistogramIndicator } from '@kbn/slo-schema'; import { SO_SLO_TYPE } from '../../../saved_objects'; import { @@ -92,6 +92,30 @@ export const createMetricCustomIndicator = ( }, }); +export const createHistogramIndicator = ( + params: Partial = {} +): HistogramIndicator => ({ + type: 'sli.histogram.custom', + params: { + index: 'my-index*', + filter: 'labels.groupId: group-3', + good: { + field: 'latency', + aggregation: 'range', + from: 0, + to: 100, + filter: '', + }, + total: { + field: 'latency', + aggregation: 'value_count', + filter: '', + }, + timestampField: 'log_timestamp', + ...params, + }, +}); + const defaultSLO: Omit = { name: 'irrelevant', description: 'irrelevant', diff --git a/x-pack/plugins/observability/server/services/slo/get_preview_data.ts b/x-pack/plugins/observability/server/services/slo/get_preview_data.ts index c63a0a604e882..e529028a22a9e 100644 --- a/x-pack/plugins/observability/server/services/slo/get_preview_data.ts +++ b/x-pack/plugins/observability/server/services/slo/get_preview_data.ts @@ -7,250 +7,311 @@ import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; -import { ALL_VALUE, GetPreviewDataParams, GetPreviewDataResponse } from '@kbn/slo-schema'; +import { + ALL_VALUE, + APMTransactionErrorRateIndicator, + GetPreviewDataParams, + GetPreviewDataResponse, + HistogramIndicator, + KQLCustomIndicator, + MetricCustomIndicator, +} from '@kbn/slo-schema'; +import { APMTransactionDurationIndicator } from '../../domain/models'; import { computeSLI } from '../../domain/services'; import { InvalidQueryError } from '../../errors'; -import { GetCustomMetricIndicatorAggregation } from './aggregations'; +import { + GetHistogramIndicatorAggregation, + GetCustomMetricIndicatorAggregation, +} from './aggregations'; export class GetPreviewData { constructor(private esClient: ElasticsearchClient) {} - public async execute(params: GetPreviewDataParams): Promise { - switch (params.indicator.type) { - case 'sli.apm.transactionDuration': - try { - const filter = []; - if (params.indicator.params.service !== ALL_VALUE) - filter.push({ - match: { 'service.name': params.indicator.params.service }, - }); - if (params.indicator.params.environment !== ALL_VALUE) - filter.push({ - match: { 'service.environment': params.indicator.params.environment }, - }); - if (params.indicator.params.transactionName !== ALL_VALUE) - filter.push({ - match: { 'transaction.name': params.indicator.params.transactionName }, - }); - if (params.indicator.params.transactionType !== ALL_VALUE) - filter.push({ - match: { 'transaction.type': params.indicator.params.transactionType }, - }); - if (!!params.indicator.params.filter) - filter.push(getElastichsearchQueryOrThrow(params.indicator.params.filter)); + private async getAPMTransactionDurationPreviewData( + indicator: APMTransactionDurationIndicator + ): Promise { + const filter = []; + if (indicator.params.service !== ALL_VALUE) + filter.push({ + match: { 'service.name': indicator.params.service }, + }); + if (indicator.params.environment !== ALL_VALUE) + filter.push({ + match: { 'service.environment': indicator.params.environment }, + }); + if (indicator.params.transactionName !== ALL_VALUE) + filter.push({ + match: { 'transaction.name': indicator.params.transactionName }, + }); + if (indicator.params.transactionType !== ALL_VALUE) + filter.push({ + match: { 'transaction.type': indicator.params.transactionType }, + }); + if (!!indicator.params.filter) + filter.push(getElastichsearchQueryOrThrow(indicator.params.filter)); - const truncatedThreshold = Math.trunc(params.indicator.params.threshold * 1000); + const truncatedThreshold = Math.trunc(indicator.params.threshold * 1000); - const result = await this.esClient.search({ - index: params.indicator.params.index, - query: { - bool: { - filter: [ - { range: { '@timestamp': { gte: 'now-60m' } } }, - { terms: { 'processor.event': ['metric'] } }, - { term: { 'metricset.name': 'transaction' } }, - { exists: { field: 'transaction.duration.histogram' } }, - ...filter, - ], + const result = await this.esClient.search({ + index: indicator.params.index, + query: { + bool: { + filter: [ + { range: { '@timestamp': { gte: 'now-60m' } } }, + { terms: { 'processor.event': ['metric'] } }, + { term: { 'metricset.name': 'transaction' } }, + { exists: { field: 'transaction.duration.histogram' } }, + ...filter, + ], + }, + }, + aggs: { + perMinute: { + date_histogram: { + field: '@timestamp', + fixed_interval: '1m', + }, + aggs: { + _good: { + range: { + field: 'transaction.duration.histogram', + ranges: [{ to: truncatedThreshold }], }, }, - aggs: { - perMinute: { - date_histogram: { - field: '@timestamp', - fixed_interval: '1m', - }, - aggs: { - _good: { - range: { - field: 'transaction.duration.histogram', - ranges: [{ to: truncatedThreshold }], - }, - }, - good: { - bucket_script: { - buckets_path: { - _good: `_good['*-${truncatedThreshold}.0']>_count`, - }, - script: 'params._good', - }, - }, - total: { - value_count: { - field: 'transaction.duration.histogram', - }, - }, + good: { + bucket_script: { + buckets_path: { + _good: `_good['*-${truncatedThreshold}.0']>_count`, }, + script: 'params._good', }, }, - }); - - // @ts-ignore buckets is not improperly typed - return result.aggregations?.perMinute.buckets.map((bucket) => ({ - date: bucket.key_as_string, - sliValue: - !!bucket.good && !!bucket.total - ? computeSLI(bucket.good.value, bucket.total.value) - : null, - })); - } catch (err) { - throw new InvalidQueryError(`Invalid ES query`); - } - case 'sli.apm.transactionErrorRate': - try { - const filter = []; - if (params.indicator.params.service !== ALL_VALUE) - filter.push({ - match: { 'service.name': params.indicator.params.service }, - }); - if (params.indicator.params.environment !== ALL_VALUE) - filter.push({ - match: { 'service.environment': params.indicator.params.environment }, - }); - if (params.indicator.params.transactionName !== ALL_VALUE) - filter.push({ - match: { 'transaction.name': params.indicator.params.transactionName }, - }); - if (params.indicator.params.transactionType !== ALL_VALUE) - filter.push({ - match: { 'transaction.type': params.indicator.params.transactionType }, - }); - if (!!params.indicator.params.filter) - filter.push(getElastichsearchQueryOrThrow(params.indicator.params.filter)); - - const result = await this.esClient.search({ - index: params.indicator.params.index, - query: { - bool: { - filter: [ - { range: { '@timestamp': { gte: 'now-60m' } } }, - { terms: { 'processor.event': ['metric'] } }, - { term: { 'metricset.name': 'transaction' } }, - { exists: { field: 'transaction.duration.histogram' } }, - { exists: { field: 'transaction.result' } }, - ...filter, - ], + total: { + value_count: { + field: 'transaction.duration.histogram', }, }, - aggs: { - perMinute: { - date_histogram: { - field: '@timestamp', - fixed_interval: '1m', - }, - aggs: { - good: { - filter: { - bool: { - should: { - match: { - 'event.outcome': 'success', - }, - }, - }, - }, - }, - total: { - value_count: { - field: 'transaction.duration.histogram', + }, + }, + }, + }); + + // @ts-ignore buckets is not improperly typed + return result.aggregations?.perMinute.buckets.map((bucket) => ({ + date: bucket.key_as_string, + sliValue: + !!bucket.good && !!bucket.total ? computeSLI(bucket.good.value, bucket.total.value) : null, + })); + } + + private async getAPMTranscationErrorPreviewData( + indicator: APMTransactionErrorRateIndicator + ): Promise { + const filter = []; + if (indicator.params.service !== ALL_VALUE) + filter.push({ + match: { 'service.name': indicator.params.service }, + }); + if (indicator.params.environment !== ALL_VALUE) + filter.push({ + match: { 'service.environment': indicator.params.environment }, + }); + if (indicator.params.transactionName !== ALL_VALUE) + filter.push({ + match: { 'transaction.name': indicator.params.transactionName }, + }); + if (indicator.params.transactionType !== ALL_VALUE) + filter.push({ + match: { 'transaction.type': indicator.params.transactionType }, + }); + if (!!indicator.params.filter) + filter.push(getElastichsearchQueryOrThrow(indicator.params.filter)); + + const result = await this.esClient.search({ + index: indicator.params.index, + query: { + bool: { + filter: [ + { range: { '@timestamp': { gte: 'now-60m' } } }, + { terms: { 'processor.event': ['metric'] } }, + { term: { 'metricset.name': 'transaction' } }, + { exists: { field: 'transaction.duration.histogram' } }, + { exists: { field: 'transaction.result' } }, + ...filter, + ], + }, + }, + aggs: { + perMinute: { + date_histogram: { + field: '@timestamp', + fixed_interval: '1m', + }, + aggs: { + good: { + filter: { + bool: { + should: { + match: { + 'event.outcome': 'success', }, }, }, }, }, - }); - - // @ts-ignore buckets is not improperly typed - return result.aggregations?.perMinute.buckets.map((bucket) => ({ - date: bucket.key_as_string, - sliValue: - !!bucket.good && !!bucket.total - ? computeSLI(bucket.good.doc_count, bucket.total.value) - : null, - })); - } catch (err) { - throw new InvalidQueryError(`Invalid ES query`); - } - case 'sli.kql.custom': - try { - const filterQuery = getElastichsearchQueryOrThrow(params.indicator.params.filter); - const goodQuery = getElastichsearchQueryOrThrow(params.indicator.params.good); - const totalQuery = getElastichsearchQueryOrThrow(params.indicator.params.total); - const timestampField = params.indicator.params.timestampField; - const result = await this.esClient.search({ - index: params.indicator.params.index, - query: { - bool: { - filter: [{ range: { [timestampField]: { gte: 'now-60m' } } }, filterQuery], - }, - }, - aggs: { - perMinute: { - date_histogram: { - field: timestampField, - fixed_interval: '1m', - }, - aggs: { - good: { filter: goodQuery }, - total: { filter: totalQuery }, - }, + total: { + value_count: { + field: 'transaction.duration.histogram', }, }, - }); + }, + }, + }, + }); - // @ts-ignore buckets is not improperly typed - return result.aggregations?.perMinute.buckets.map((bucket) => ({ - date: bucket.key_as_string, - sliValue: - !!bucket.good && !!bucket.total - ? computeSLI(bucket.good.doc_count, bucket.total.doc_count) - : null, - })); - } catch (err) { - throw new InvalidQueryError(`Invalid ES query`); - } - case 'sli.metric.custom': - const timestampField = params.indicator.params.timestampField; - const filterQuery = getElastichsearchQueryOrThrow(params.indicator.params.filter); - const getCustomMetricIndicatorAggregation = new GetCustomMetricIndicatorAggregation( - params.indicator - ); - const result = await this.esClient.search({ - index: params.indicator.params.index, - query: { - bool: { - filter: [{ range: { [timestampField]: { gte: 'now-60m' } } }, filterQuery], - }, + // @ts-ignore buckets is not improperly typed + return result.aggregations?.perMinute.buckets.map((bucket) => ({ + date: bucket.key_as_string, + sliValue: + !!bucket.good && !!bucket.total + ? computeSLI(bucket.good.doc_count, bucket.total.value) + : null, + })); + } + + private async getHistogramPreviewData( + indicator: HistogramIndicator + ): Promise { + const getHistogramIndicatorAggregations = new GetHistogramIndicatorAggregation(indicator); + const filterQuery = getElastichsearchQueryOrThrow(indicator.params.filter); + const timestampField = indicator.params.timestampField; + const options = { + index: indicator.params.index, + query: { + bool: { + filter: [{ range: { [timestampField]: { gte: 'now-60m' } } }, filterQuery], + }, + }, + aggs: { + perMinute: { + date_histogram: { + field: timestampField, + fixed_interval: '1m', }, aggs: { - perMinute: { - date_histogram: { - field: timestampField, - fixed_interval: '1m', - }, - aggs: { - ...getCustomMetricIndicatorAggregation.execute({ - type: 'good', - aggregationKey: 'good', - }), - ...getCustomMetricIndicatorAggregation.execute({ - type: 'total', - aggregationKey: 'total', - }), - }, - }, + ...getHistogramIndicatorAggregations.execute({ + type: 'good', + aggregationKey: 'good', + }), + ...getHistogramIndicatorAggregations.execute({ + type: 'total', + aggregationKey: 'total', + }), }, - }); + }, + }, + }; + const result = await this.esClient.search(options); + + // @ts-ignore buckets is not improperly typed + return result.aggregations?.perMinute.buckets.map((bucket) => ({ + date: bucket.key_as_string, + sliValue: + !!bucket.good && !!bucket.total ? computeSLI(bucket.good.value, bucket.total.value) : null, + })); + } - // @ts-ignore buckets is not improperly typed - return result.aggregations?.perMinute.buckets.map((bucket) => ({ - date: bucket.key_as_string, - sliValue: - !!bucket.good && !!bucket.total - ? computeSLI(bucket.good.value, bucket.total.value) - : null, - })); + private async getCustomMetricPreviewData( + indicator: MetricCustomIndicator + ): Promise { + const timestampField = indicator.params.timestampField; + const filterQuery = getElastichsearchQueryOrThrow(indicator.params.filter); + const getCustomMetricIndicatorAggregation = new GetCustomMetricIndicatorAggregation(indicator); + const result = await this.esClient.search({ + index: indicator.params.index, + query: { + bool: { + filter: [{ range: { [timestampField]: { gte: 'now-60m' } } }, filterQuery], + }, + }, + aggs: { + perMinute: { + date_histogram: { + field: timestampField, + fixed_interval: '1m', + }, + aggs: { + ...getCustomMetricIndicatorAggregation.execute({ + type: 'good', + aggregationKey: 'good', + }), + ...getCustomMetricIndicatorAggregation.execute({ + type: 'total', + aggregationKey: 'total', + }), + }, + }, + }, + }); + // @ts-ignore buckets is not improperly typed + return result.aggregations?.perMinute.buckets.map((bucket) => ({ + date: bucket.key_as_string, + sliValue: + !!bucket.good && !!bucket.total ? computeSLI(bucket.good.value, bucket.total.value) : null, + })); + } + + private async getCustomKQLPreviewData( + indicator: KQLCustomIndicator + ): Promise { + const filterQuery = getElastichsearchQueryOrThrow(indicator.params.filter); + const goodQuery = getElastichsearchQueryOrThrow(indicator.params.good); + const totalQuery = getElastichsearchQueryOrThrow(indicator.params.total); + const timestampField = indicator.params.timestampField; + const result = await this.esClient.search({ + index: indicator.params.index, + query: { + bool: { + filter: [{ range: { [timestampField]: { gte: 'now-60m' } } }, filterQuery], + }, + }, + aggs: { + perMinute: { + date_histogram: { + field: timestampField, + fixed_interval: '1m', + }, + aggs: { + good: { filter: goodQuery }, + total: { filter: totalQuery }, + }, + }, + }, + }); + + // @ts-ignore buckets is not improperly typed + return result.aggregations?.perMinute.buckets.map((bucket) => ({ + date: bucket.key_as_string, + sliValue: + !!bucket.good && !!bucket.total + ? computeSLI(bucket.good.doc_count, bucket.total.doc_count) + : null, + })); + } + + public async execute(params: GetPreviewDataParams): Promise { + switch (params.indicator.type) { + case 'sli.apm.transactionDuration': + return this.getAPMTransactionDurationPreviewData(params.indicator); + case 'sli.apm.transactionErrorRate': + return this.getAPMTranscationErrorPreviewData(params.indicator); + case 'sli.kql.custom': + return this.getCustomKQLPreviewData(params.indicator); + case 'sli.histogram.custom': + return this.getHistogramPreviewData(params.indicator); + case 'sli.metric.custom': + return this.getCustomMetricPreviewData(params.indicator); default: return []; } diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/histogram.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/histogram.test.ts.snap new file mode 100644 index 0000000000000..81ad6c77c9564 --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/histogram.test.ts.snap @@ -0,0 +1,317 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Histogram Transform Generator aggregates using the denominator equation 1`] = ` +Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_total>total", + }, + "script": "params.value", + }, +} +`; + +exports[`Histogram Transform Generator aggregates using the denominator equation with filter 1`] = ` +Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_total>total", + }, + "script": "params.value", + }, +} +`; + +exports[`Histogram Transform Generator aggregates using the numerator equation 1`] = ` +Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_good>total['0.0-100.0']>_count", + }, + "script": "params.value", + }, +} +`; + +exports[`Histogram Transform Generator aggregates using the numerator equation with filter 1`] = ` +Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_good>total['0.0-100.0']>_count", + }, + "script": "params.value", + }, +} +`; + +exports[`Histogram Transform Generator filters the source using the kql query 1`] = ` +Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "labels.groupId": "group-4", + }, + }, + ], + }, +} +`; + +exports[`Histogram Transform Generator returns the expected transform params for timeslices slo 1`] = ` +Object { + "_meta": Object { + "managed": true, + "managed_by": "observability", + "version": 1, + }, + "description": "Rolled-up SLI data for SLO: irrelevant", + "dest": Object { + "index": ".slo-observability.sli-v1", + "pipeline": ".slo-observability.sli.monthly", + }, + "frequency": "1m", + "pivot": Object { + "aggregations": Object { + "_good": Object { + "aggs": Object { + "total": Object { + "range": Object { + "field": "latency", + "keyed": true, + "ranges": Array [ + Object { + "from": 0, + "to": 100, + }, + ], + }, + }, + }, + "filter": Object { + "match_all": Object {}, + }, + }, + "_total": Object { + "aggs": Object { + "total": Object { + "value_count": Object { + "field": "latency", + }, + }, + }, + "filter": Object { + "match_all": Object {}, + }, + }, + "slo.denominator": Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_total>total", + }, + "script": "params.value", + }, + }, + "slo.isGoodSlice": Object { + "bucket_script": Object { + "buckets_path": Object { + "goodEvents": "slo.numerator>value", + "totalEvents": "slo.denominator>value", + }, + "script": "params.goodEvents / params.totalEvents >= 0.95 ? 1 : 0", + }, + }, + "slo.numerator": Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_good>total['0.0-100.0']>_count", + }, + "script": "params.value", + }, + }, + }, + "group_by": Object { + "@timestamp": Object { + "date_histogram": Object { + "field": "log_timestamp", + "fixed_interval": "2m", + }, + }, + "slo.id": Object { + "terms": Object { + "field": "slo.id", + }, + }, + "slo.revision": Object { + "terms": Object { + "field": "slo.revision", + }, + }, + }, + }, + "settings": Object { + "deduce_mappings": false, + }, + "source": Object { + "index": "my-index*", + "query": Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "labels.groupId": "group-3", + }, + }, + ], + }, + }, + "runtime_mappings": Object { + "slo.id": Object { + "script": Object { + "source": Any, + }, + "type": "keyword", + }, + "slo.revision": Object { + "script": Object { + "source": "emit(1)", + }, + "type": "long", + }, + }, + }, + "sync": Object { + "time": Object { + "delay": "1m", + "field": "log_timestamp", + }, + }, + "transform_id": Any, +} +`; + +exports[`Histogram Transform Generator returns the expected transform params with every specified indicator params 1`] = ` +Object { + "_meta": Object { + "managed": true, + "managed_by": "observability", + "version": 1, + }, + "description": "Rolled-up SLI data for SLO: irrelevant", + "dest": Object { + "index": ".slo-observability.sli-v1", + "pipeline": ".slo-observability.sli.monthly", + }, + "frequency": "1m", + "pivot": Object { + "aggregations": Object { + "_good": Object { + "aggs": Object { + "total": Object { + "range": Object { + "field": "latency", + "keyed": true, + "ranges": Array [ + Object { + "from": 0, + "to": 100, + }, + ], + }, + }, + }, + "filter": Object { + "match_all": Object {}, + }, + }, + "_total": Object { + "aggs": Object { + "total": Object { + "value_count": Object { + "field": "latency", + }, + }, + }, + "filter": Object { + "match_all": Object {}, + }, + }, + "slo.denominator": Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_total>total", + }, + "script": "params.value", + }, + }, + "slo.numerator": Object { + "bucket_script": Object { + "buckets_path": Object { + "value": "_good>total['0.0-100.0']>_count", + }, + "script": "params.value", + }, + }, + }, + "group_by": Object { + "@timestamp": Object { + "date_histogram": Object { + "field": "log_timestamp", + "fixed_interval": "1m", + }, + }, + "slo.id": Object { + "terms": Object { + "field": "slo.id", + }, + }, + "slo.revision": Object { + "terms": Object { + "field": "slo.revision", + }, + }, + }, + }, + "settings": Object { + "deduce_mappings": false, + }, + "source": Object { + "index": "my-index*", + "query": Object { + "bool": Object { + "minimum_should_match": 1, + "should": Array [ + Object { + "match": Object { + "labels.groupId": "group-3", + }, + }, + ], + }, + }, + "runtime_mappings": Object { + "slo.id": Object { + "script": Object { + "source": Any, + }, + "type": "keyword", + }, + "slo.revision": Object { + "script": Object { + "source": "emit(1)", + }, + "type": "long", + }, + }, + }, + "sync": Object { + "time": Object { + "delay": "1m", + "field": "log_timestamp", + }, + }, + "transform_id": Any, +} +`; diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.test.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.test.ts new file mode 100644 index 0000000000000..fdf0bc27563fe --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.test.ts @@ -0,0 +1,162 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + createHistogramIndicator, + createSLO, + createSLOWithTimeslicesBudgetingMethod, +} from '../fixtures/slo'; +import { HistogramTransformGenerator } from './histogram'; + +const generator = new HistogramTransformGenerator(); + +describe('Histogram Transform Generator', () => { + describe('validation', () => { + it('throws when the good filter is invalid', () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator({ + good: { + field: 'latency', + aggregation: 'range', + from: 0, + to: 100, + filter: 'foo:', + }, + }), + }); + expect(() => generator.getTransformParams(anSLO)).toThrow(/Invalid KQL: foo:/); + }); + it('throws when the total filter is invalid', () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator({ + good: { + field: 'latency', + aggregation: 'value_count', + filter: 'foo:', + }, + }), + }); + expect(() => generator.getTransformParams(anSLO)).toThrow(/Invalid KQL: foo:/); + }); + it('throws when the query_filter is invalid', () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator({ filter: '{ kql.query: invalid' }), + }); + expect(() => generator.getTransformParams(anSLO)).toThrow(/Invalid KQL/); + }); + }); + + it('returns the expected transform params with every specified indicator params', async () => { + const anSLO = createSLO({ indicator: createHistogramIndicator() }); + const transform = generator.getTransformParams(anSLO); + + expect(transform).toMatchSnapshot({ + transform_id: expect.any(String), + source: { runtime_mappings: { 'slo.id': { script: { source: expect.any(String) } } } }, + }); + expect(transform.transform_id).toEqual(`slo-${anSLO.id}-${anSLO.revision}`); + expect(transform.source.runtime_mappings!['slo.id']).toMatchObject({ + script: { source: `emit('${anSLO.id}')` }, + }); + expect(transform.source.runtime_mappings!['slo.revision']).toMatchObject({ + script: { source: `emit(${anSLO.revision})` }, + }); + }); + + it('returns the expected transform params for timeslices slo', async () => { + const anSLO = createSLOWithTimeslicesBudgetingMethod({ + indicator: createHistogramIndicator(), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform).toMatchSnapshot({ + transform_id: expect.any(String), + source: { runtime_mappings: { 'slo.id': { script: { source: expect.any(String) } } } }, + }); + }); + + it('filters the source using the kql query', async () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator({ filter: 'labels.groupId: group-4' }), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform.source.query).toMatchSnapshot(); + }); + + it('uses the provided index', async () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator({ index: 'my-own-index*' }), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform.source.index).toBe('my-own-index*'); + }); + + it('uses the provided timestampField', async () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator({ + timestampField: 'my-date-field', + }), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform.sync?.time?.field).toBe('my-date-field'); + // @ts-ignore + expect(transform.pivot?.group_by['@timestamp'].date_histogram.field).toBe('my-date-field'); + }); + + it('aggregates using the numerator equation', async () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator(), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform.pivot!.aggregations!['slo.numerator']).toMatchSnapshot(); + }); + + it('aggregates using the numerator equation with filter', async () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator({ + good: { + field: 'latency', + aggregation: 'range', + from: 0, + to: 100, + filter: 'foo: "bar"', + }, + }), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform.pivot!.aggregations!['slo.numerator']).toMatchSnapshot(); + }); + + it('aggregates using the denominator equation', async () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator(), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform.pivot!.aggregations!['slo.denominator']).toMatchSnapshot(); + }); + + it('aggregates using the denominator equation with filter', async () => { + const anSLO = createSLO({ + indicator: createHistogramIndicator({ + total: { + field: 'latency', + aggregation: 'value_count', + filter: 'foo: "bar"', + }, + }), + }); + const transform = generator.getTransformParams(anSLO); + + expect(transform.pivot!.aggregations!['slo.denominator']).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.ts new file mode 100644 index 0000000000000..f120d27d98a8a --- /dev/null +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.ts @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/types'; +import { + HistogramIndicator, + histogramIndicatorSchema, + timeslicesBudgetingMethodSchema, +} from '@kbn/slo-schema'; + +import { InvalidTransformError } from '../../../errors'; +import { getSLOTransformTemplate } from '../../../assets/transform_templates/slo_transform_template'; +import { getElastichsearchQueryOrThrow, TransformGenerator } from '.'; +import { + SLO_DESTINATION_INDEX_NAME, + SLO_INGEST_PIPELINE_NAME, + getSLOTransformId, +} from '../../../assets/constants'; +import { SLO } from '../../../domain/models'; +import { GetHistogramIndicatorAggregation } from '../aggregations'; + +export class HistogramTransformGenerator extends TransformGenerator { + public getTransformParams(slo: SLO): TransformPutTransformRequest { + if (!histogramIndicatorSchema.is(slo.indicator)) { + throw new InvalidTransformError(`Cannot handle SLO of indicator type: ${slo.indicator.type}`); + } + + return getSLOTransformTemplate( + this.buildTransformId(slo), + this.buildDescription(slo), + this.buildSource(slo, slo.indicator), + this.buildDestination(), + this.buildGroupBy(slo, slo.indicator.params.timestampField), + this.buildAggregations(slo, slo.indicator), + this.buildSettings(slo, slo.indicator.params.timestampField) + ); + } + + private buildTransformId(slo: SLO): string { + return getSLOTransformId(slo.id, slo.revision); + } + + private buildSource(slo: SLO, indicator: HistogramIndicator) { + const filter = getElastichsearchQueryOrThrow(indicator.params.filter); + return { + index: indicator.params.index, + runtime_mappings: this.buildCommonRuntimeMappings(slo), + query: filter, + }; + } + + private buildDestination() { + return { + pipeline: SLO_INGEST_PIPELINE_NAME, + index: SLO_DESTINATION_INDEX_NAME, + }; + } + + private buildAggregations(slo: SLO, indicator: HistogramIndicator) { + const getHistogramIndicatorAggregations = new GetHistogramIndicatorAggregation(indicator); + + return { + ...getHistogramIndicatorAggregations.execute({ + type: 'good', + aggregationKey: 'slo.numerator', + }), + ...getHistogramIndicatorAggregations.execute({ + type: 'total', + aggregationKey: 'slo.denominator', + }), + ...(timeslicesBudgetingMethodSchema.is(slo.budgetingMethod) && { + 'slo.isGoodSlice': { + bucket_script: { + buckets_path: { + goodEvents: 'slo.numerator>value', + totalEvents: 'slo.denominator>value', + }, + script: `params.goodEvents / params.totalEvents >= ${slo.objective.timesliceTarget} ? 1 : 0`, + }, + }, + }), + }; + } +} diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/index.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/index.ts index 80e66c4134ceb..2b9337546d796 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/index.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/index.ts @@ -10,4 +10,5 @@ export * from './apm_transaction_error_rate'; export * from './apm_transaction_duration'; export * from './kql_custom'; export * from './metric_custom'; +export * from './histogram'; export * from './common'; From ea0aed276d7c0528bd46eed24e9bb72990acd95e Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Tue, 11 Jul 2023 20:23:38 -0400 Subject: [PATCH 48/97] feat(slo): handles tab from url in slo details page (#161222) --- .../use_fetch_historical_summary.ts | 2 +- .../hooks/slo/use_fetch_historical_summary.ts | 4 +- .../slo_details/components/slo_details.tsx | 41 +++++++++++++------ .../pages/slo_details/slo_details.test.tsx | 9 ++-- .../public/pages/slo_details/slo_details.tsx | 3 -- .../pages/slos/components/slo_list_items.tsx | 4 +- .../public/pages/slos/slos.test.tsx | 20 ++++----- 7 files changed, 50 insertions(+), 33 deletions(-) diff --git a/x-pack/plugins/observability/public/hooks/slo/__storybook_mocks__/use_fetch_historical_summary.ts b/x-pack/plugins/observability/public/hooks/slo/__storybook_mocks__/use_fetch_historical_summary.ts index 7928dbe51b46d..783e71f800d30 100644 --- a/x-pack/plugins/observability/public/hooks/slo/__storybook_mocks__/use_fetch_historical_summary.ts +++ b/x-pack/plugins/observability/public/hooks/slo/__storybook_mocks__/use_fetch_historical_summary.ts @@ -24,6 +24,6 @@ export const useFetchHistoricalSummary = ({ isRefetching: false, isSuccess: false, isError: false, - sloHistoricalSummaryResponse: data, + data, }; }; diff --git a/x-pack/plugins/observability/public/hooks/slo/use_fetch_historical_summary.ts b/x-pack/plugins/observability/public/hooks/slo/use_fetch_historical_summary.ts index f304a241786bc..060985b3effdf 100644 --- a/x-pack/plugins/observability/public/hooks/slo/use_fetch_historical_summary.ts +++ b/x-pack/plugins/observability/public/hooks/slo/use_fetch_historical_summary.ts @@ -12,7 +12,7 @@ import { useKibana } from '../../utils/kibana_react'; import { sloKeys } from './query_key_factory'; export interface UseFetchHistoricalSummaryResponse { - sloHistoricalSummaryResponse: FetchHistoricalSummaryResponse | undefined; + data: FetchHistoricalSummaryResponse | undefined; isInitialLoading: boolean; isRefetching: boolean; isLoading: boolean; @@ -55,7 +55,7 @@ export function useFetchHistoricalSummary({ }); return { - sloHistoricalSummaryResponse: data, + data, isLoading, isRefetching, isInitialLoading, diff --git a/x-pack/plugins/observability/public/pages/slo_details/components/slo_details.tsx b/x-pack/plugins/observability/public/pages/slo_details/components/slo_details.tsx index 48cb87a9c8ec9..b2f08b5d69030 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/components/slo_details.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/components/slo_details.tsx @@ -14,9 +14,10 @@ import { EuiTabbedContentTab, } from '@elastic/eui'; import { SLOWithSummaryResponse } from '@kbn/slo-schema'; -import React, { Fragment } from 'react'; +import React, { Fragment, useState } from 'react'; import { i18n } from '@kbn/i18n'; +import { useLocation } from 'react-router-dom'; import { useFetchActiveAlerts } from '../../../hooks/slo/use_fetch_active_alerts'; import { formatHistoricalData } from '../../../utils/slo/chart_data_formatter'; import { useFetchHistoricalSummary } from '../../../hooks/slo/use_fetch_historical_summary'; @@ -30,25 +31,28 @@ export interface Props { slo: SLOWithSummaryResponse; isAutoRefreshing: boolean; } -const OVERVIEW_TAB = 'overview'; -const ALERTS_TAB = 'alerts'; + +const TAB_ID_URL_PARAM = 'tabId'; +const OVERVIEW_TAB_ID = 'overview'; +const ALERTS_TAB_ID = 'alerts'; + +type TabId = typeof OVERVIEW_TAB_ID | typeof ALERTS_TAB_ID; export function SloDetails({ slo, isAutoRefreshing }: Props) { - const { data: activeAlerts } = useFetchActiveAlerts({ - sloIds: [slo.id], - }); - const { isLoading: historicalSummaryLoading, sloHistoricalSummaryResponse = {} } = + const { search } = useLocation(); + const { data: activeAlerts } = useFetchActiveAlerts({ sloIds: [slo.id] }); + const { isLoading: historicalSummaryLoading, data: historicalSummaryBySlo = {} } = useFetchHistoricalSummary({ sloIds: [slo.id], shouldRefetch: isAutoRefreshing }); const errorBudgetBurnDownData = formatHistoricalData( - sloHistoricalSummaryResponse[slo.id], + historicalSummaryBySlo[slo.id], 'error_budget_remaining' ); - const historicalSliData = formatHistoricalData(sloHistoricalSummaryResponse[slo.id], 'sli_value'); + const historicalSliData = formatHistoricalData(historicalSummaryBySlo[slo.id], 'sli_value'); const tabs: EuiTabbedContentTab[] = [ { - id: OVERVIEW_TAB, + id: OVERVIEW_TAB_ID, name: i18n.translate('xpack.observability.slo.sloDetails.tab.overviewLabel', { defaultMessage: 'Overview', }), @@ -84,7 +88,7 @@ export function SloDetails({ slo, isAutoRefreshing }: Props) { ), }, { - id: ALERTS_TAB, + id: ALERTS_TAB_ID, name: i18n.translate('xpack.observability.slo.sloDetails.tab.alertsLabel', { defaultMessage: 'Alerts', }), @@ -98,11 +102,24 @@ export function SloDetails({ slo, isAutoRefreshing }: Props) { }, ]; + const [selectedTabId, setSelectedTabId] = useState(() => { + const searchParams = new URLSearchParams(search); + const urlTabId = searchParams.get(TAB_ID_URL_PARAM); + return urlTabId && [OVERVIEW_TAB_ID, ALERTS_TAB_ID].includes(urlTabId) + ? (urlTabId as TabId) + : OVERVIEW_TAB_ID; + }); + + const handleSelectedTab = (newTabId: TabId) => { + setSelectedTabId(newTabId); + }; + return ( tab.id === selectedTabId) ?? tabs[0]} + onTabClick={(tab) => handleSelectedTab(tab.id as TabId)} /> ); } diff --git a/x-pack/plugins/observability/public/pages/slo_details/slo_details.test.tsx b/x-pack/plugins/observability/public/pages/slo_details/slo_details.test.tsx index c52fd9a0bd8fc..2c1a1ebcae875 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/slo_details.test.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/slo_details.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { fireEvent, screen, waitFor } from '@testing-library/react'; import { useKibana } from '../../utils/kibana_react'; -import { useParams } from 'react-router-dom'; +import { useParams, useLocation } from 'react-router-dom'; import { useLicense } from '../../hooks/use_license'; import { useCapabilities } from '../../hooks/slo/use_capabilities'; import { useFetchSloDetails } from '../../hooks/slo/use_fetch_slo_details'; @@ -31,6 +31,7 @@ import { buildApmAvailabilityIndicator } from '../../data/slo/indicator'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useParams: jest.fn(), + useLocation: jest.fn(), })); jest.mock('@kbn/observability-shared-plugin/public'); @@ -45,6 +46,7 @@ jest.mock('../../hooks/slo/use_delete_slo'); const useKibanaMock = useKibana as jest.Mock; const useParamsMock = useParams as jest.Mock; +const useLocationMock = useLocation as jest.Mock; const useLicenseMock = useLicense as jest.Mock; const useCapabilitiesMock = useCapabilities as jest.Mock; const useFetchActiveAlertsMock = useFetchActiveAlerts as jest.Mock; @@ -105,11 +107,12 @@ describe('SLO Details Page', () => { useCapabilitiesMock.mockReturnValue({ hasWriteCapabilities: true, hasReadCapabilities: true }); useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: historicalSummaryData, + data: historicalSummaryData, }); useFetchActiveAlertsMock.mockReturnValue({ isLoading: false, data: {} }); useCloneSloMock.mockReturnValue({ mutate: mockClone }); useDeleteSloMock.mockReturnValue({ mutate: mockDelete }); + useLocationMock.mockReturnValue({ search: '' }); }); describe('when the incorrect license is found', () => { @@ -155,7 +158,7 @@ describe('SLO Details Page', () => { useLicenseMock.mockReturnValue({ hasAtLeast: () => true }); useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: true, - sloHistoricalSummaryResponse: {}, + data: {}, }); render(); diff --git a/x-pack/plugins/observability/public/pages/slo_details/slo_details.tsx b/x-pack/plugins/observability/public/pages/slo_details/slo_details.tsx index 00d6fb4db0762..1531e3305fc52 100644 --- a/x-pack/plugins/observability/public/pages/slo_details/slo_details.tsx +++ b/x-pack/plugins/observability/public/pages/slo_details/slo_details.tsx @@ -39,11 +39,8 @@ export function SloDetailsPage() { const hasRightLicense = hasAtLeast('platinum'); const { sloId } = useParams(); - const [isAutoRefreshing, setIsAutoRefreshing] = useState(true); - const { isLoading, slo } = useFetchSloDetails({ sloId, shouldRefetch: isAutoRefreshing }); - const isCloningOrDeleting = Boolean(useIsMutating()); useBreadcrumbs(getBreadcrumbs(basePath, slo)); diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_list_items.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_list_items.tsx index e70f8139fe9f5..2eb790e404b30 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_list_items.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_list_items.tsx @@ -27,7 +27,7 @@ export function SloListItems({ sloList, loading, error }: Props) { const { data: activeAlertsBySlo } = useFetchActiveAlerts({ sloIds }); const { data: rulesBySlo } = useFetchRulesForSlo({ sloIds }); - const { isLoading: historicalSummaryLoading, sloHistoricalSummaryResponse } = + const { isLoading: historicalSummaryLoading, data: historicalSummaryBySlo } = useFetchHistoricalSummary({ sloIds }); const { mutate: deleteSlo } = useDeleteSlo(); @@ -50,7 +50,7 @@ export function SloListItems({ sloList, loading, error }: Props) { { useLicenseMock.mockReturnValue({ hasAtLeast: () => false }); useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: {}, + data: {}, }); }); it('navigates to the SLOs Welcome Page', async () => { @@ -135,7 +135,7 @@ describe('SLOs Page', () => { useFetchSloListMock.mockReturnValue({ isLoading: false, sloList: emptySloList }); useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: {}, + data: {}, }); await act(async () => { @@ -152,7 +152,7 @@ describe('SLOs Page', () => { useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: historicalSummaryData, + data: historicalSummaryData, }); await act(async () => { @@ -167,7 +167,7 @@ describe('SLOs Page', () => { useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: historicalSummaryData, + data: historicalSummaryData, }); await act(async () => { @@ -183,7 +183,7 @@ describe('SLOs Page', () => { useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: historicalSummaryData, + data: historicalSummaryData, }); await act(async () => { @@ -201,7 +201,7 @@ describe('SLOs Page', () => { useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: historicalSummaryData, + data: historicalSummaryData, }); await act(async () => { @@ -228,7 +228,7 @@ describe('SLOs Page', () => { useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: historicalSummaryData, + data: historicalSummaryData, }); await act(async () => { @@ -253,7 +253,7 @@ describe('SLOs Page', () => { useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: historicalSummaryData, + data: historicalSummaryData, }); await act(async () => { @@ -278,7 +278,7 @@ describe('SLOs Page', () => { useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: historicalSummaryData, + data: historicalSummaryData, }); await act(async () => { @@ -308,7 +308,7 @@ describe('SLOs Page', () => { useFetchHistoricalSummaryMock.mockReturnValue({ isLoading: false, - sloHistoricalSummaryResponse: historicalSummaryData, + data: historicalSummaryData, }); await act(async () => { From ca3146f0ca5dc1d003214878bbf60d0aa1f00a1d Mon Sep 17 00:00:00 2001 From: Luke <11671118+lgestc@users.noreply.github.com> Date: Wed, 12 Jul 2023 03:02:11 +0200 Subject: [PATCH 49/97] [Security Solution] Store last conversation in localstorage #6993 (#161373) --- .../assistant/assistant_overlay/index.tsx | 16 +- .../impl/assistant/index.test.tsx | 163 ++++++++++++++++++ .../impl/assistant/index.tsx | 19 +- .../impl/assistant_context/constants.tsx | 1 + .../impl/assistant_context/index.tsx | 10 ++ .../impl/assistant_context/types.tsx | 6 +- .../mock/test_providers/test_providers.tsx | 15 +- .../kbn-elastic-assistant/tsconfig.json | 1 + .../assistant/content/conversations/index.tsx | 1 + 9 files changed, 219 insertions(+), 13 deletions(-) create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/index.test.tsx diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx index 285bc26240954..32f0b48aa2a23 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx @@ -36,7 +36,7 @@ export const AssistantOverlay = React.memo(({ isAssistantEnabled }) => { WELCOME_CONVERSATION_TITLE ); const [promptContextId, setPromptContextId] = useState(); - const { setShowAssistantOverlay } = useAssistantContext(); + const { setShowAssistantOverlay, localStorageLastConversationId } = useAssistantContext(); // Bind `showAssistantOverlay` in SecurityAssistantContext to this modal instance const showOverlay = useCallback( @@ -56,15 +56,25 @@ export const AssistantOverlay = React.memo(({ isAssistantEnabled }) => { setShowAssistantOverlay(showOverlay); }, [setShowAssistantOverlay, showOverlay]); + // Called whenever platform specific shortcut for assistant is pressed + const handleShortcutPress = useCallback(() => { + // Try to restore the last conversation on shortcut pressed + if (!isModalVisible) { + setConversationId(localStorageLastConversationId || WELCOME_CONVERSATION_TITLE); + } + + setIsModalVisible(!isModalVisible); + }, [isModalVisible, localStorageLastConversationId]); + // Register keyboard listener to show the modal when cmd + ; is pressed const onKeyDown = useCallback( (event: KeyboardEvent) => { if (event.key === ';' && (isMac ? event.metaKey : event.ctrlKey)) { event.preventDefault(); - setIsModalVisible(!isModalVisible); + handleShortcutPress(); } }, - [isModalVisible] + [handleShortcutPress] ); useEvent('keydown', onKeyDown); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.test.tsx new file mode 100644 index 0000000000000..44f50e26c1115 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.test.tsx @@ -0,0 +1,163 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { act, fireEvent, render, screen } from '@testing-library/react'; +import { Assistant } from '.'; +import { Conversation } from '../assistant_context/types'; +import type { IHttpFetchError } from '@kbn/core/public'; +import { ActionConnector } from '@kbn/triggers-actions-ui-plugin/public'; + +import { useLoadConnectors } from '../connectorland/use_load_connectors'; +import { useConnectorSetup } from '../connectorland/connector_setup'; + +import { UseQueryResult } from '@tanstack/react-query'; +import { WELCOME_CONVERSATION_TITLE } from './use_conversation/translations'; + +import { useLocalStorage } from 'react-use'; +import { PromptEditor } from './prompt_editor'; +import { QuickPrompts } from './quick_prompts/quick_prompts'; +import { TestProviders } from '../mock/test_providers/test_providers'; + +jest.mock('../connectorland/use_load_connectors'); +jest.mock('../connectorland/connector_setup'); +jest.mock('react-use'); + +jest.mock('./prompt_editor', () => ({ PromptEditor: jest.fn() })); +jest.mock('./quick_prompts/quick_prompts', () => ({ QuickPrompts: jest.fn() })); + +const MOCK_CONVERSATION_TITLE = 'electric sheep'; + +const getInitialConversations = (): Record => ({ + [WELCOME_CONVERSATION_TITLE]: { + id: WELCOME_CONVERSATION_TITLE, + messages: [], + apiConfig: {}, + }, + [MOCK_CONVERSATION_TITLE]: { + id: MOCK_CONVERSATION_TITLE, + messages: [], + apiConfig: {}, + }, +}); + +const renderAssistant = () => + render( + + + + ); + +describe('Assistant', () => { + beforeAll(() => { + jest.mocked(useConnectorSetup).mockReturnValue({ + comments: [], + prompt: <>, + }); + + jest.mocked(PromptEditor).mockReturnValue(null); + jest.mocked(QuickPrompts).mockReturnValue(null); + }); + + let persistToLocalStorage: jest.Mock; + + beforeEach(() => { + jest.clearAllMocks(); + persistToLocalStorage = jest.fn(); + + jest + .mocked(useLocalStorage) + .mockReturnValue([undefined, persistToLocalStorage] as unknown as ReturnType< + typeof useLocalStorage + >); + }); + + describe('when selected conversation changes and some connectors are loaded', () => { + it('should persist the conversation id to local storage', async () => { + const connectors: unknown[] = [{}]; + + jest.mocked(useLoadConnectors).mockReturnValue({ + isSuccess: true, + data: connectors, + } as unknown as UseQueryResult); + + renderAssistant(); + + expect(persistToLocalStorage).toHaveBeenCalled(); + + expect(persistToLocalStorage).toHaveBeenLastCalledWith(WELCOME_CONVERSATION_TITLE); + + const previousConversationButton = screen.getByLabelText('Previous conversation'); + + expect(previousConversationButton).toBeInTheDocument(); + await act(async () => { + fireEvent.click(previousConversationButton); + }); + + expect(persistToLocalStorage).toHaveBeenLastCalledWith('electric sheep'); + }); + + it('should not persist the conversation id to local storage when excludeFromLastConversationStorage flag is indicated', async () => { + const connectors: unknown[] = [{}]; + + jest.mocked(useLoadConnectors).mockReturnValue({ + isSuccess: true, + data: connectors, + } as unknown as UseQueryResult); + + const { getByLabelText } = render( + ({ + [WELCOME_CONVERSATION_TITLE]: { + id: WELCOME_CONVERSATION_TITLE, + messages: [], + apiConfig: {}, + }, + [MOCK_CONVERSATION_TITLE]: { + id: MOCK_CONVERSATION_TITLE, + messages: [], + apiConfig: {}, + excludeFromLastConversationStorage: true, + }, + })} + > + + + ); + + expect(persistToLocalStorage).toHaveBeenCalled(); + + expect(persistToLocalStorage).toHaveBeenLastCalledWith(WELCOME_CONVERSATION_TITLE); + + const previousConversationButton = getByLabelText('Previous conversation'); + + expect(previousConversationButton).toBeInTheDocument(); + + await act(async () => { + fireEvent.click(previousConversationButton); + }); + expect(persistToLocalStorage).toHaveBeenLastCalledWith(WELCOME_CONVERSATION_TITLE); + }); + }); + + describe('when no connectors are loaded', () => { + it('should clear conversation id in local storage', async () => { + const emptyConnectors: unknown[] = []; + + jest.mocked(useLoadConnectors).mockReturnValue({ + isSuccess: true, + data: emptyConnectors, + } as unknown as UseQueryResult); + + renderAssistant(); + + expect(persistToLocalStorage).toHaveBeenCalled(); + expect(persistToLocalStorage).toHaveBeenLastCalledWith(''); + }); + }); +}); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx index 8e1af141ede65..58e084db643af 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx @@ -81,6 +81,7 @@ const AssistantComponent: React.FC = ({ getComments, http, promptContexts, + setLastConversationId, title, allSystemPrompts, } = useAssistantContext(); @@ -136,7 +137,11 @@ const AssistantComponent: React.FC = ({ }; }, [conversations, isAssistantEnabled, selectedConversationId]); - const { data: connectors, refetch: refetchConnectors } = useLoadConnectors({ http }); + const { + data: connectors, + isSuccess: areConnectorsFetched, + refetch: refetchConnectors, + } = useLoadConnectors({ http }); const defaultConnectorId = useMemo(() => connectors?.[0]?.id, [connectors]); const defaultProvider = useMemo( () => @@ -145,6 +150,18 @@ const AssistantComponent: React.FC = ({ [connectors] ); + // Remember last selection for reuse after keyboard shortcut is pressed. + // Clear it if there is no connectors + useEffect(() => { + if (areConnectorsFetched && !connectors?.length) { + return setLastConversationId(''); + } + + if (!currentConversation.excludeFromLastConversationStorage) { + setLastConversationId(currentConversation.id); + } + }, [areConnectorsFetched, connectors?.length, currentConversation, setLastConversationId]); + const isWelcomeSetup = (connectors?.length ?? 0) === 0; const isDisabled = isWelcomeSetup || !isAssistantEnabled; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/constants.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/constants.tsx index bfe62a2848a9f..cad3783c4669b 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/constants.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/constants.tsx @@ -8,3 +8,4 @@ export const DEFAULT_ASSISTANT_NAMESPACE = 'elasticAssistantDefault'; export const QUICK_PROMPT_LOCAL_STORAGE_KEY = 'quickPrompts'; export const SYSTEM_PROMPT_LOCAL_STORAGE_KEY = 'systemPrompts'; +export const LAST_CONVERSATION_ID_LOCAL_STORAGE_KEY = 'lastConversationId'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx index 7a3c2e0dde870..3bce0e7f86041 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx @@ -28,6 +28,7 @@ import { Prompt } from '../assistant/types'; import { BASE_SYSTEM_PROMPTS } from '../content/prompts/system'; import { DEFAULT_ASSISTANT_NAMESPACE, + LAST_CONVERSATION_ID_LOCAL_STORAGE_KEY, QUICK_PROMPT_LOCAL_STORAGE_KEY, SYSTEM_PROMPT_LOCAL_STORAGE_KEY, } from './constants'; @@ -99,6 +100,7 @@ interface UseAssistantContext { showAnonymizedValues: boolean; }) => EuiCommentProps[]; http: HttpSetup; + localStorageLastConversationId: string | undefined; promptContexts: Record; nameSpace: string; registerPromptContext: RegisterPromptContext; @@ -107,6 +109,7 @@ interface UseAssistantContext { setConversations: React.Dispatch>>; setDefaultAllow: React.Dispatch>; setDefaultAllowReplacement: React.Dispatch>; + setLastConversationId: React.Dispatch>; setShowAssistantOverlay: (showAssistantOverlay: ShowAssistantOverlay) => void; showAssistantOverlay: ShowAssistantOverlay; title: string; @@ -158,6 +161,9 @@ export const AssistantProvider: React.FC = ({ setLocalStorageSystemPrompts(baseSystemPrompts); }, [baseSystemPrompts, setLocalStorageSystemPrompts]); + const [localStorageLastConversationId, setLocalStorageLastConversationId] = + useLocalStorage(`${nameSpace}.${LAST_CONVERSATION_ID_LOCAL_STORAGE_KEY}`); + /** * Prompt contexts are used to provide components a way to register and make their data available to the assistant. */ @@ -259,6 +265,8 @@ export const AssistantProvider: React.FC = ({ showAssistantOverlay, title, unRegisterPromptContext, + localStorageLastConversationId, + setLastConversationId: setLocalStorageLastConversationId, }), [ actionTypeRegistry, @@ -275,6 +283,7 @@ export const AssistantProvider: React.FC = ({ docLinks, getComments, http, + localStorageLastConversationId, localStorageQuickPrompts, localStorageSystemPrompts, nameSpace, @@ -283,6 +292,7 @@ export const AssistantProvider: React.FC = ({ registerPromptContext, setDefaultAllow, setDefaultAllowReplacement, + setLocalStorageLastConversationId, setLocalStorageQuickPrompts, setLocalStorageSystemPrompts, showAssistantOverlay, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx index 766b79586dd25..e0b0ff128cfa0 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx @@ -53,9 +53,5 @@ export interface Conversation { replacements?: Record; theme?: ConversationTheme; isDefault?: boolean; -} - -export interface OpenAIConfig { - temperature: number; - model: string; + excludeFromLastConversationStorage?: boolean; } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/mock/test_providers/test_providers.tsx b/x-pack/packages/kbn-elastic-assistant/impl/mock/test_providers/test_providers.tsx index 63fe8cf0d0984..1569cdba9afbb 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/mock/test_providers/test_providers.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/mock/test_providers/test_providers.tsx @@ -14,17 +14,24 @@ import React from 'react'; import { ThemeProvider } from 'styled-components'; import { AssistantProvider } from '../../assistant_context'; +import { Conversation } from '../../assistant_context/types'; interface Props { children: React.ReactNode; + getInitialConversations?: () => Record; } window.scrollTo = jest.fn(); +window.HTMLElement.prototype.scrollIntoView = jest.fn(); + +const mockGetInitialConversations = () => ({}); /** A utility for wrapping children in the providers required to run tests */ -export const TestProvidersComponent: React.FC = ({ children }) => { +export const TestProvidersComponent: React.FC = ({ + children, + getInitialConversations = mockGetInitialConversations, +}) => { const actionTypeRegistry = actionTypeRegistryMock.create(); - const mockGetInitialConversations = jest.fn(() => ({})); const mockGetComments = jest.fn(() => []); const mockHttp = httpServiceMock.createStartContract({ basePath: '/test' }); @@ -33,7 +40,7 @@ export const TestProvidersComponent: React.FC = ({ children }) => { ({ eui: euiDarkVars, darkMode: true })}> = ({ children }) => { DOC_LINK_VERSION: 'current', }} getComments={mockGetComments} - getInitialConversations={mockGetInitialConversations} + getInitialConversations={getInitialConversations} setConversations={jest.fn()} setDefaultAllow={jest.fn()} setDefaultAllowReplacement={jest.fn()} diff --git a/x-pack/packages/kbn-elastic-assistant/tsconfig.json b/x-pack/packages/kbn-elastic-assistant/tsconfig.json index 05fde2f37756c..a4f71df75c834 100644 --- a/x-pack/packages/kbn-elastic-assistant/tsconfig.json +++ b/x-pack/packages/kbn-elastic-assistant/tsconfig.json @@ -28,5 +28,6 @@ "@kbn/i18n-react", "@kbn/ui-theme", "@kbn/core-doc-links-browser", + "@kbn/core", ] } diff --git a/x-pack/plugins/security_solution/public/assistant/content/conversations/index.tsx b/x-pack/plugins/security_solution/public/assistant/content/conversations/index.tsx index b2e4993d9763d..eb93ae100e00f 100644 --- a/x-pack/plugins/security_solution/public/assistant/content/conversations/index.tsx +++ b/x-pack/plugins/security_solution/public/assistant/content/conversations/index.tsx @@ -45,6 +45,7 @@ export const BASE_SECURITY_CONVERSATIONS: Record = { apiConfig: {}, }, [TIMELINE_CONVERSATION_TITLE]: { + excludeFromLastConversationStorage: true, id: TIMELINE_CONVERSATION_TITLE, isDefault: true, messages: [], From 8ece07a0e9da0094f3389315373592934b394c19 Mon Sep 17 00:00:00 2001 From: Sander Philipse <94373878+sphilipse@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:22:18 +0800 Subject: [PATCH 50/97] [Enterprise Search] Add ServiceNow connector (#161651) ## Summary Add ServiceNow in the right spot. --- .../enterprise_search/common/connectors/connectors.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/x-pack/plugins/enterprise_search/common/connectors/connectors.ts b/x-pack/plugins/enterprise_search/common/connectors/connectors.ts index 2883057a06a3b..1acdb588b2f3f 100644 --- a/x-pack/plugins/enterprise_search/common/connectors/connectors.ts +++ b/x-pack/plugins/enterprise_search/common/connectors/connectors.ts @@ -160,6 +160,17 @@ export const CONNECTOR_DEFINITIONS: ConnectorServerSideDefinition[] = [ }), serviceType: 's3', }, + { + iconPath: 'servicenow.svg', + isBeta: true, + isNative: false, + isTechPreview: false, + keywords: ['servicenow', 'cloud', 'connector'], + name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.serviceNow.name', { + defaultMessage: 'ServiceNow', + }), + serviceType: 'servicenow', + }, { iconPath: 'sharepoint_server.svg', isBeta: true, From 665b8871857df8d61a8ffd66411004f4fb07ebe4 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:10:53 -0400 Subject: [PATCH 51/97] [api-docs] 2023-07-12 Daily api_docs build (#161721) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/396 --- api_docs/actions.devdocs.json | 14 + api_docs/actions.mdx | 4 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.devdocs.json | 4 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_chat_provider.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.devdocs.json | 24 + api_docs/data.mdx | 4 +- api_docs/data_query.mdx | 4 +- api_docs/data_search.devdocs.json | 242 -- api_docs/data_search.mdx | 4 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.devdocs.json | 3016 ++++++----------- api_docs/data_views.mdx | 4 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 14 +- api_docs/deprecations_by_plugin.mdx | 22 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.devdocs.json | 41 + api_docs/dev_tools.mdx | 4 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...agement_table_list_view_table.devdocs.json | 4 +- ...ntent_management_table_list_view_table.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 4 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.devdocs.json | 4 - api_docs/kbn_core_http_server.mdx | 2 +- ...kbn_core_http_server_internal.devdocs.json | 6 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- .../kbn_core_http_server_mocks.devdocs.json | 4 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- .../kbn_core_lifecycle_browser.devdocs.json | 28 - api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- ...ore_saved_objects_api_browser.devdocs.json | 12 - .../kbn_core_saved_objects_api_browser.mdx | 2 +- ...core_saved_objects_api_server.devdocs.json | 12 - .../kbn_core_saved_objects_api_server.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- ...e_saved_objects_browser_mocks.devdocs.json | 8 - .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- ...kbn_core_saved_objects_common.devdocs.json | 8 - api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- ...kbn_core_saved_objects_server.devdocs.json | 12 - api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.devdocs.json | 401 +-- api_docs/kbn_dom_drag_drop.mdx | 4 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_assistant.devdocs.json | 30 +- api_docs/kbn_elastic_assistant.mdx | 4 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_generate_csv_types.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.devdocs.json | 981 +++++- api_docs/kbn_slo_schema.mdx | 4 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.devdocs.json | 24 + api_docs/kibana_react.mdx | 4 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.devdocs.json | 395 +-- api_docs/lens.mdx | 4 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/logs_shared.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.devdocs.json | 472 ++- api_docs/observability.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 30 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/reporting_export_types.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.devdocs.json | 82 +- api_docs/saved_search.mdx | 4 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.devdocs.json | 213 +- api_docs/task_manager.mdx | 4 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.devdocs.json | 160 + api_docs/triggers_actions_ui.mdx | 4 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualization_ui_components.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 569 files changed, 3759 insertions(+), 3616 deletions(-) diff --git a/api_docs/actions.devdocs.json b/api_docs/actions.devdocs.json index 4dceb2257dfaf..77efc367450b5 100644 --- a/api_docs/actions.devdocs.json +++ b/api_docs/actions.devdocs.json @@ -3004,6 +3004,20 @@ "path": "x-pack/plugins/actions/server/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "actions", + "id": "def-server.InMemoryConnector.config", + "type": "Uncategorized", + "tags": [], + "label": "config", + "description": [], + "signature": [ + "Config" + ], + "path": "x-pack/plugins/actions/server/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 1a6fedafa8960..0e0ab4c5351bb 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 271 | 10 | 266 | 27 | +| 272 | 10 | 267 | 27 | ## Client diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index 1346511a6ca20..e1d6969e6cb84 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 9bb1b36da3a9d..5f9b975ef5fc9 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 112424a70875f..4a5ed373058a6 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -7766,12 +7766,12 @@ { "parentPluginId": "alerting", "id": "def-common.Rule.scheduledTaskId", - "type": "string", + "type": "CompoundType", "tags": [], "label": "scheduledTaskId", "description": [], "signature": [ - "string | undefined" + "string | null | undefined" ], "path": "x-pack/plugins/alerting/common/rule.ts", "deprecated": false, diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index f46942f7c9d09..0a5831e816202 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 6ab38c8fb83be..eea9228dc13a1 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index 0d1c81c34bd8f..187f8cac08c6e 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index ca82c22e2196e..1657a91e26407 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 67dea5c91c68d..1a7203b15daf6 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index d8e7736076997..04935e3ace356 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 75a0add7d9a54..b478758a50d19 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 9e2ec06ff9c06..53ed6a8ebd0c5 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 6ab6035380325..56591da514f14 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 1da11c1d53f4c..e3cda9d91fcec 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index b62b81b2abe04..b8aab15383ec9 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 67f9cfec54546..d68eada8d0f96 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index 7d6825a1fbc5d..a1dedd8339ebd 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index d0ae7d741d943..5c6eded66b586 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 05f4f08bb093b..224ea106b3a70 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 2267b0df25500..c735c48198d89 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index 397f6e9cc5556..88b58e1006119 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 0fe12f4e7a81e..f6243d77450ae 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index d8a3ac72a369b..2311c13d9dab5 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 49300ed1d840b..050b47851a7cd 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index 8611aefc84052..b4fc147092548 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index 96f9a3585ba9d..8caf2b094d26d 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -13368,6 +13368,18 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/alerts_actions/utils.test.ts" }, + { + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" + }, + { + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" + }, + { + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" + }, { "plugin": "@kbn/es-query", "path": "packages/kbn-es-query/src/es_query/build_es_query.test.ts" @@ -21019,6 +21031,18 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/alerts_actions/utils.test.ts" }, + { + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" + }, + { + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" + }, + { + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" + }, { "plugin": "@kbn/es-query", "path": "packages/kbn-es-query/src/es_query/build_es_query.test.ts" diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 56f3fafc21aa4..52eb0626413b2 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3303 | 119 | 2583 | 27 | +| 3291 | 119 | 2571 | 27 | ## Client diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 338da741c67d9..db9e19d2ca004 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3303 | 119 | 2583 | 27 | +| 3291 | 119 | 2571 | 27 | ## Client diff --git a/api_docs/data_search.devdocs.json b/api_docs/data_search.devdocs.json index 50fcede8aa2a7..1b61dd4313160 100644 --- a/api_docs/data_search.devdocs.json +++ b/api_docs/data_search.devdocs.json @@ -14315,78 +14315,6 @@ "returnComment": [], "initialIsOpen": false }, - { - "parentPluginId": "data", - "id": "def-common.getKibanaContextFn", - "type": "Function", - "tags": [], - "label": "getKibanaContextFn", - "description": [], - "signature": [ - "(getStartDependencies: (getKibanaRequest: (() => ", - { - "pluginId": "@kbn/core-http-server", - "scope": "common", - "docId": "kibKbnCoreHttpServerPluginApi", - "section": "def-common.KibanaRequest", - "text": "KibanaRequest" - }, - ") | undefined) => Promise<", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.KibanaContextStartDependencies", - "text": "KibanaContextStartDependencies" - }, - ">) => ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.ExpressionFunctionKibanaContext", - "text": "ExpressionFunctionKibanaContext" - } - ], - "path": "src/plugins/data/common/search/expressions/kibana_context.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.getKibanaContextFn.$1", - "type": "Function", - "tags": [], - "label": "getStartDependencies", - "description": [], - "signature": [ - "(getKibanaRequest: (() => ", - { - "pluginId": "@kbn/core-http-server", - "scope": "common", - "docId": "kibKbnCoreHttpServerPluginApi", - "section": "def-common.KibanaRequest", - "text": "KibanaRequest" - }, - ") | undefined) => Promise<", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.KibanaContextStartDependencies", - "text": "KibanaContextStartDependencies" - }, - ">" - ], - "path": "src/plugins/data/common/search/expressions/kibana_context.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "data", "id": "def-common.getMaxMetricAgg", @@ -28748,40 +28676,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "data", - "id": "def-common.KibanaContextStartDependencies", - "type": "Interface", - "tags": [], - "label": "KibanaContextStartDependencies", - "description": [], - "path": "src/plugins/data/common/search/expressions/kibana_context.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.KibanaContextStartDependencies.savedObjectsClient", - "type": "Object", - "tags": [], - "label": "savedObjectsClient", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.SavedObjectsClientCommon", - "text": "SavedObjectsClientCommon" - } - ], - "path": "src/plugins/data/common/search/expressions/kibana_context.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "data", "id": "def-common.MetricAggParam", @@ -38157,142 +38051,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "data", - "id": "def-common.kibanaContext", - "type": "Object", - "tags": [], - "label": "kibanaContext", - "description": [], - "path": "src/plugins/data/common/search/expressions/kibana_context_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.kibanaContext.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "path": "src/plugins/data/common/search/expressions/kibana_context_type.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "data", - "id": "def-common.kibanaContext.from", - "type": "Object", - "tags": [], - "label": "from", - "description": [], - "path": "src/plugins/data/common/search/expressions/kibana_context_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.kibanaContext.from.null", - "type": "Function", - "tags": [], - "label": "null", - "description": [], - "signature": [ - "() => { type: string; }" - ], - "path": "src/plugins/data/common/search/expressions/kibana_context_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - } - ] - }, - { - "parentPluginId": "data", - "id": "def-common.kibanaContext.to", - "type": "Object", - "tags": [], - "label": "to", - "description": [], - "path": "src/plugins/data/common/search/expressions/kibana_context_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.kibanaContext.to.null", - "type": "Function", - "tags": [], - "label": "null", - "description": [], - "signature": [ - "() => { type: string; }" - ], - "path": "src/plugins/data/common/search/expressions/kibana_context_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "data", - "id": "def-common.kibanaContext.to.filter", - "type": "Function", - "tags": [], - "label": "filter", - "description": [], - "signature": [ - "(input: ", - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.ExpressionValueSearchContext", - "text": "ExpressionValueSearchContext" - }, - ") => ", - { - "pluginId": "expressions", - "scope": "common", - "docId": "kibExpressionsPluginApi", - "section": "def-common.ExpressionValueFilter", - "text": "ExpressionValueFilter" - } - ], - "path": "src/plugins/data/common/search/expressions/kibana_context_type.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "data", - "id": "def-common.kibanaContext.to.filter.$1", - "type": "CompoundType", - "tags": [], - "label": "input", - "description": [], - "signature": [ - { - "pluginId": "data", - "scope": "common", - "docId": "kibDataSearchPluginApi", - "section": "def-common.ExpressionValueSearchContext", - "text": "ExpressionValueSearchContext" - } - ], - "path": "src/plugins/data/common/search/expressions/kibana_context_type.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - } - ] - } - ], - "initialIsOpen": false - }, { "parentPluginId": "data", "id": "def-common.kibanaFilterFunction", diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 8e22c13954f0b..7f25bf9e7a12f 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3303 | 119 | 2583 | 27 | +| 3291 | 119 | 2571 | 27 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 9c497707bf63a..c1e0159f6932f 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 044a03392088c..d700893466595 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 2242242ceeef3..af4c7eb88725a 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.devdocs.json b/api_docs/data_views.devdocs.json index b766d077cdf92..f25ea1813e233 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -188,16 +188,16 @@ "path": "x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/alerts_actions/utils.test.ts" }, { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.test.ts" + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" }, { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.test.ts" + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" }, { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.test.ts" + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" }, { "plugin": "@kbn/es-query", @@ -5465,35 +5465,35 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon", + "id": "def-public.UiSettingsPublicToCommon", "type": "Class", "tags": [], - "label": "SavedObjectsClientPublicToCommon", + "label": "UiSettingsPublicToCommon", "description": [], "signature": [ { "pluginId": "dataViews", "scope": "public", "docId": "kibDataViewsPluginApi", - "section": "def-public.SavedObjectsClientPublicToCommon", - "text": "SavedObjectsClientPublicToCommon" + "section": "def-public.UiSettingsPublicToCommon", + "text": "UiSettingsPublicToCommon" }, " implements ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.SavedObjectsClientCommon", - "text": "SavedObjectsClientCommon" + "section": "def-common.UiSettingsCommon", + "text": "UiSettingsCommon" } ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.Unnamed", + "id": "def-public.UiSettingsPublicToCommon.Unnamed", "type": "Function", "tags": [], "label": "Constructor", @@ -5501,104 +5501,27 @@ "signature": [ "any" ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.Unnamed.$1", - "type": "Object", - "tags": [], - "label": "contentManagementClient", - "description": [], - "signature": [ - { - "pluginId": "contentManagement", - "scope": "public", - "docId": "kibContentManagementPluginApi", - "section": "def-public.ContentClient", - "text": "ContentClient" - } - ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.Unnamed.$2", - "type": "Object", - "tags": [], - "label": "savedObjectClient", - "description": [], - "signature": [ - "SOClient" - ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.find", - "type": "Function", - "tags": [], - "label": "find", - "description": [], - "signature": [ - "(options: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.SavedObjectsClientCommonFindArgs", - "text": "SavedObjectsClientCommonFindArgs" - }, - ") => Promise<", - { - "pluginId": "@kbn/content-management-utils", - "scope": "common", - "docId": "kibKbnContentManagementUtilsPluginApi", - "section": "def-common.SOWithMetadata", - "text": "SOWithMetadata" - }, - "<", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ">[]>" - ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.find.$1", + "id": "def-public.UiSettingsPublicToCommon.Unnamed.$1", "type": "Object", "tags": [], - "label": "options", + "label": "uiSettings", "description": [], "signature": [ { - "pluginId": "dataViews", + "pluginId": "@kbn/core-ui-settings-browser", "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.SavedObjectsClientCommonFindArgs", - "text": "SavedObjectsClientCommonFindArgs" + "docId": "kibKbnCoreUiSettingsBrowserPluginApi", + "section": "def-common.IUiSettingsClient", + "text": "IUiSettingsClient" } ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -5608,45 +5531,29 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.get", + "id": "def-public.UiSettingsPublicToCommon.get", "type": "Function", "tags": [], "label": "get", "description": [], "signature": [ - "(id: string) => Promise<", - { - "pluginId": "@kbn/content-management-utils", - "scope": "common", - "docId": "kibKbnContentManagementUtilsPluginApi", - "section": "def-common.SOWithMetadata", - "text": "SOWithMetadata" - }, - "<", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ">>" + "(key: string) => Promise" ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.get.$1", + "id": "def-public.UiSettingsPublicToCommon.get.$1", "type": "string", "tags": [], - "label": "id", + "label": "key", "description": [], "signature": [ "string" ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -5656,129 +5563,76 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.getSavedSearch", + "id": "def-public.UiSettingsPublicToCommon.getAll", "type": "Function", "tags": [], - "label": "getSavedSearch", + "label": "getAll", "description": [], "signature": [ - "(id: string) => Promise<", + "() => Promise>" + ") | undefined>>" ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.getSavedSearch.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], + "children": [], "returnComment": [] }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.update", + "id": "def-public.UiSettingsPublicToCommon.set", "type": "Function", "tags": [], - "label": "update", + "label": "set", "description": [], "signature": [ - "(id: string, attributes: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ", options: DataViewUpdateOptions) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - "<", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ">>" + "(key: string, value: unknown) => Promise" ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.update.$1", + "id": "def-public.UiSettingsPublicToCommon.set.$1", "type": "string", "tags": [], - "label": "id", + "label": "key", "description": [], "signature": [ "string" ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.update.$2", - "type": "Object", - "tags": [], - "label": "attributes", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - } - ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "isRequired": true }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.update.$3", - "type": "Object", + "id": "def-public.UiSettingsPublicToCommon.set.$2", + "type": "Unknown", "tags": [], - "label": "options", + "label": "value", "description": [], "signature": [ - "DataViewUpdateOptions" + "unknown" ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -5788,318 +5642,29 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.create", + "id": "def-public.UiSettingsPublicToCommon.remove", "type": "Function", "tags": [], - "label": "create", + "label": "remove", "description": [], "signature": [ - "(attributes: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ", options: DataViewCreateOptions) => Promise<", - { - "pluginId": "@kbn/content-management-utils", - "scope": "common", - "docId": "kibKbnContentManagementUtilsPluginApi", - "section": "def-common.SOWithMetadata", - "text": "SOWithMetadata" - }, - "<", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ">>" + "(key: string) => Promise" ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.create.$1", - "type": "Object", - "tags": [], - "label": "attributes", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - } - ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.create.$2", - "type": "Object", + "id": "def-public.UiSettingsPublicToCommon.remove.$1", + "type": "string", "tags": [], - "label": "options", + "label": "key", "description": [], "signature": [ - "DataViewCreateOptions" + "string" ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.delete", - "type": "Function", - "tags": [], - "label": "delete", - "description": [], - "signature": [ - "(id: string) => Promise" - ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientPublicToCommon.delete.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon", - "type": "Class", - "tags": [], - "label": "UiSettingsPublicToCommon", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "public", - "docId": "kibDataViewsPluginApi", - "section": "def-public.UiSettingsPublicToCommon", - "text": "UiSettingsPublicToCommon" - }, - " implements ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.UiSettingsCommon", - "text": "UiSettingsCommon" - } - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.Unnamed", - "type": "Function", - "tags": [], - "label": "Constructor", - "description": [], - "signature": [ - "any" - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.Unnamed.$1", - "type": "Object", - "tags": [], - "label": "uiSettings", - "description": [], - "signature": [ - { - "pluginId": "@kbn/core-ui-settings-browser", - "scope": "common", - "docId": "kibKbnCoreUiSettingsBrowserPluginApi", - "section": "def-common.IUiSettingsClient", - "text": "IUiSettingsClient" - } - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.get", - "type": "Function", - "tags": [], - "label": "get", - "description": [], - "signature": [ - "(key: string) => Promise" - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.get.$1", - "type": "string", - "tags": [], - "label": "key", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.getAll", - "type": "Function", - "tags": [], - "label": "getAll", - "description": [], - "signature": [ - "() => Promise) | undefined>>" - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.set", - "type": "Function", - "tags": [], - "label": "set", - "description": [], - "signature": [ - "(key: string, value: unknown) => Promise" - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.set.$1", - "type": "string", - "tags": [], - "label": "key", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.set.$2", - "type": "Unknown", - "tags": [], - "label": "value", - "description": [], - "signature": [ - "unknown" - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.remove", - "type": "Function", - "tags": [], - "label": "remove", - "description": [], - "signature": [ - "(key: string) => Promise" - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.UiSettingsPublicToCommon.remove.$1", - "type": "string", - "tags": [], - "label": "key", - "description": [], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", + "path": "src/plugins/data_views/public/ui_settings_wrapper.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -7439,84 +7004,20 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.RuntimeField", + "id": "def-public.PersistenceAPI", "type": "Interface", "tags": [], - "label": "RuntimeField", + "label": "PersistenceAPI", "description": [ - "\nThis is the RuntimeField interface enhanced with Data view field\nconfiguration: field format definition, customLabel or popularity." + "\nCommon interface for the saved objects client on server and content management in browser" ], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.RuntimeField", - "text": "RuntimeField" - }, - " extends ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.RuntimeFieldBase", - "text": "RuntimeFieldBase" - }, - ",", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldConfiguration", - "text": "FieldConfiguration" - } - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.RuntimeField.fields", - "type": "Object", - "tags": [], - "label": "fields", - "description": [ - "\nSubfields of composite field" - ], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.RuntimeFieldSubFields", - "text": "RuntimeFieldSubFields" - }, - " | undefined" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon", - "type": "Interface", - "tags": [], - "label": "SavedObjectsClientCommon", - "description": [ - "\nCommon interface for the saved objects client" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.find", + "id": "def-public.PersistenceAPI.find", "type": "Function", "tags": [], "label": "find", @@ -7556,7 +7057,7 @@ "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.find.$1", + "id": "def-public.PersistenceAPI.find.$1", "type": "Object", "tags": [], "label": "options", @@ -7582,7 +7083,7 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.get", + "id": "def-public.PersistenceAPI.get", "type": "Function", "tags": [], "label": "get", @@ -7614,51 +7115,7 @@ "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.get.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- id of saved object" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.getSavedSearch", - "type": "Function", - "tags": [], - "label": "getSavedSearch", - "description": [ - "\nUpdate a saved object by id" - ], - "signature": [ - "(id: string) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - ">" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.getSavedSearch.$1", + "id": "def-public.PersistenceAPI.get.$1", "type": "string", "tags": [], "label": "id", @@ -7678,7 +7135,7 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.update", + "id": "def-public.PersistenceAPI.update", "type": "Function", "tags": [], "label": "update", @@ -7710,7 +7167,7 @@ "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.update.$1", + "id": "def-public.PersistenceAPI.update.$1", "type": "string", "tags": [], "label": "id", @@ -7727,7 +7184,7 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.update.$2", + "id": "def-public.PersistenceAPI.update.$2", "type": "Object", "tags": [], "label": "attributes", @@ -7750,7 +7207,7 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.update.$3", + "id": "def-public.PersistenceAPI.update.$3", "type": "Object", "tags": [], "label": "options", @@ -7761,7 +7218,7 @@ "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.update.$3.version", + "id": "def-public.PersistenceAPI.update.$3.version", "type": "string", "tags": [], "label": "version", @@ -7780,7 +7237,7 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.create", + "id": "def-public.PersistenceAPI.create", "type": "Function", "tags": [], "label": "create", @@ -7812,7 +7269,7 @@ "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.create.$1", + "id": "def-public.PersistenceAPI.create.$1", "type": "Object", "tags": [], "label": "attributes", @@ -7835,7 +7292,7 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.create.$2", + "id": "def-public.PersistenceAPI.create.$2", "type": "Object", "tags": [], "label": "options", @@ -7846,7 +7303,7 @@ "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.create.$2.id", + "id": "def-public.PersistenceAPI.create.$2.id", "type": "string", "tags": [], "label": "id", @@ -7860,7 +7317,7 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.create.$2.initialNamespaces", + "id": "def-public.PersistenceAPI.create.$2.initialNamespaces", "type": "Array", "tags": [], "label": "initialNamespaces", @@ -7874,7 +7331,7 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.create.$2.overwrite", + "id": "def-public.PersistenceAPI.create.$2.overwrite", "type": "CompoundType", "tags": [], "label": "overwrite", @@ -7893,7 +7350,7 @@ }, { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.delete", + "id": "def-public.PersistenceAPI.delete", "type": "Function", "tags": [], "label": "delete", @@ -7909,7 +7366,7 @@ "children": [ { "parentPluginId": "dataViews", - "id": "def-public.SavedObjectsClientCommon.delete.$1", + "id": "def-public.PersistenceAPI.delete.$1", "type": "string", "tags": [], "label": "id", @@ -7930,6 +7387,70 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "dataViews", + "id": "def-public.RuntimeField", + "type": "Interface", + "tags": [], + "label": "RuntimeField", + "description": [ + "\nThis is the RuntimeField interface enhanced with Data view field\nconfiguration: field format definition, customLabel or popularity." + ], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.RuntimeField", + "text": "RuntimeField" + }, + " extends ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.RuntimeFieldBase", + "text": "RuntimeFieldBase" + }, + ",", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.FieldConfiguration", + "text": "FieldConfiguration" + } + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-public.RuntimeField.fields", + "type": "Object", + "tags": [], + "label": "fields", + "description": [ + "\nSubfields of composite field" + ], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.RuntimeFieldSubFields", + "text": "RuntimeFieldSubFields" + }, + " | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "dataViews", "id": "def-public.Tag", @@ -8503,16 +8024,16 @@ "path": "x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/alerts_actions/utils.test.ts" }, { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.test.ts" + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" }, { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.test.ts" + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" }, { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.test.ts" + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" }, { "plugin": "@kbn/es-query", @@ -13579,491 +13100,62 @@ } ], "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "dataViews", + "id": "def-server.DATA_VIEW_PATH", + "type": "string", + "tags": [], + "label": "DATA_VIEW_PATH", + "description": [ + "\nPath for data view creation" + ], + "path": "src/plugins/data_views/server/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false }, { "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon", - "type": "Interface", + "id": "def-server.DATA_VIEW_PATH_LEGACY", + "type": "string", "tags": [], - "label": "SavedObjectsClientCommon", + "label": "DATA_VIEW_PATH_LEGACY", "description": [ - "\nCommon interface for the saved objects client" + "\nLegacy path for data view creation" ], - "path": "src/plugins/data_views/common/types.ts", + "path": "src/plugins/data_views/server/constants.ts", "deprecated": false, "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.find", - "type": "Function", - "tags": [], - "label": "find", - "description": [ - "\nSearch for saved objects" - ], - "signature": [ - "(options: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.SavedObjectsClientCommonFindArgs", - "text": "SavedObjectsClientCommonFindArgs" - }, - ") => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - "<", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ">[]>" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.find.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [ - "- options for search" - ], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.SavedObjectsClientCommonFindArgs", - "text": "SavedObjectsClientCommonFindArgs" - } - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.get", - "type": "Function", - "tags": [], - "label": "get", - "description": [ - "\nGet a single saved object by id" - ], - "signature": [ - "(id: string) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - "<", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ">>" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.get.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- id of saved object" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.getSavedSearch", - "type": "Function", - "tags": [], - "label": "getSavedSearch", - "description": [ - "\nUpdate a saved object by id" - ], - "signature": [ - "(id: string) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - ">" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.getSavedSearch.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- id of saved object" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.update", - "type": "Function", - "tags": [], - "label": "update", - "description": [ - "\nUpdate a saved object by id" - ], - "signature": [ - "(id: string, attributes: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ", options: { version?: string | undefined; }) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - ">" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.update.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- id of saved object" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.update.$2", - "type": "Object", - "tags": [], - "label": "attributes", - "description": [ - "- attributes to update" - ], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - } - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.update.$3", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.update.$3.version", - "type": "string", - "tags": [], - "label": "version", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false - } - ] - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.create", - "type": "Function", - "tags": [], - "label": "create", - "description": [ - "\nCreate a saved object" - ], - "signature": [ - "(attributes: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; overwrite?: boolean | undefined; }) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - ">" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.create.$1", - "type": "Object", - "tags": [], - "label": "attributes", - "description": [ - "- attributes to set" - ], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - } - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.create.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.create.$2.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.create.$2.initialNamespaces", - "type": "Array", - "tags": [], - "label": "initialNamespaces", - "description": [], - "signature": [ - "string[] | undefined" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.create.$2.overwrite", - "type": "CompoundType", - "tags": [], - "label": "overwrite", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false - } - ] - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.delete", - "type": "Function", - "tags": [], - "label": "delete", - "description": [ - "\nDelete a saved object by id" - ], - "signature": [ - "(id: string) => Promise" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-server.SavedObjectsClientCommon.delete.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- id of saved object" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - } - ], - "initialIsOpen": false - } - ], - "enums": [], - "misc": [ - { - "parentPluginId": "dataViews", - "id": "def-server.DATA_VIEW_PATH", - "type": "string", - "tags": [], - "label": "DATA_VIEW_PATH", - "description": [ - "\nPath for data view creation" - ], - "path": "src/plugins/data_views/server/constants.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, - { - "parentPluginId": "dataViews", - "id": "def-server.DATA_VIEW_PATH_LEGACY", - "type": "string", - "tags": [], - "label": "DATA_VIEW_PATH_LEGACY", - "description": [ - "\nLegacy path for data view creation" - ], - "path": "src/plugins/data_views/server/constants.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, - { - "parentPluginId": "dataViews", - "id": "def-server.DATA_VIEW_SWAP_REFERENCES_PATH", - "type": "string", - "tags": [], - "label": "DATA_VIEW_SWAP_REFERENCES_PATH", - "description": [ - "\nPath to swap references" - ], - "path": "src/plugins/data_views/server/constants.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, - { - "parentPluginId": "dataViews", - "id": "def-server.FieldSpec", - "type": "Type", - "tags": [], - "label": "FieldSpec", - "description": [ - "\nSerialized version of DataViewField" - ], - "signature": [ + "initialIsOpen": false + }, + { + "parentPluginId": "dataViews", + "id": "def-server.DATA_VIEW_SWAP_REFERENCES_PATH", + "type": "string", + "tags": [], + "label": "DATA_VIEW_SWAP_REFERENCES_PATH", + "description": [ + "\nPath to swap references" + ], + "path": "src/plugins/data_views/server/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "dataViews", + "id": "def-server.FieldSpec", + "type": "Type", + "tags": [], + "label": "FieldSpec", + "description": [ + "\nSerialized version of DataViewField" + ], + "signature": [ { "pluginId": "@kbn/es-query", "scope": "common", @@ -15887,16 +14979,16 @@ "path": "x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/alerts_actions/utils.test.ts" }, { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.test.ts" + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" }, { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.test.ts" + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" }, { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.test.ts" + "plugin": "savedSearch", + "path": "src/plugins/saved_search/common/expressions/kibana_context.test.ts" }, { "plugin": "@kbn/es-query", @@ -21450,8 +20542,8 @@ "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.SavedObjectsClientCommon", - "text": "SavedObjectsClientCommon" + "section": "def-common.PersistenceAPI", + "text": "PersistenceAPI" } ], "path": "src/plugins/data_views/common/data_views/data_views.ts", @@ -23526,57 +22618,286 @@ }, { "parentPluginId": "dataViews", - "id": "def-common.GetFieldsOptions.includeUnmapped", - "type": "CompoundType", + "id": "def-common.GetFieldsOptions.includeUnmapped", + "type": "CompoundType", + "tags": [], + "label": "includeUnmapped", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.GetFieldsOptions.fields", + "type": "Array", + "tags": [], + "label": "fields", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.HasDataService", + "type": "Interface", + "tags": [], + "label": "HasDataService", + "description": [], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.HasDataService.hasESData", + "type": "Function", + "tags": [], + "label": "hasESData", + "description": [], + "signature": [ + "() => Promise" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "dataViews", + "id": "def-common.HasDataService.hasUserDataView", + "type": "Function", + "tags": [], + "label": "hasUserDataView", + "description": [], + "signature": [ + "() => Promise" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "dataViews", + "id": "def-common.HasDataService.hasDataView", + "type": "Function", + "tags": [], + "label": "hasDataView", + "description": [], + "signature": [ + "() => Promise" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.IDataViewsApiClient", + "type": "Interface", + "tags": [], + "label": "IDataViewsApiClient", + "description": [], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.IDataViewsApiClient.getFieldsForWildcard", + "type": "Function", "tags": [], - "label": "includeUnmapped", + "label": "getFieldsForWildcard", "description": [], "signature": [ - "boolean | undefined" + "(options: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.GetFieldsOptions", + "text": "GetFieldsOptions" + }, + ") => Promise<", + "FieldsForWildcardResponse", + ">" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.IDataViewsApiClient.getFieldsForWildcard.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.GetFieldsOptions", + "text": "GetFieldsOptions" + } + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] }, { "parentPluginId": "dataViews", - "id": "def-common.GetFieldsOptions.fields", - "type": "Array", + "id": "def-common.IDataViewsApiClient.hasUserDataView", + "type": "Function", "tags": [], - "label": "fields", + "label": "hasUserDataView", "description": [], "signature": [ - "string[] | undefined" + "() => Promise" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false }, { "parentPluginId": "dataViews", - "id": "def-common.HasDataService", + "id": "def-common.IIndexPatternFieldList", "type": "Interface", "tags": [], - "label": "HasDataService", - "description": [], - "path": "src/plugins/data_views/common/types.ts", + "label": "IIndexPatternFieldList", + "description": [ + "\nInterface for data view field list which _extends_ the array class." + ], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.IIndexPatternFieldList", + "text": "IIndexPatternFieldList" + }, + " extends ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + }, + "[]" + ], + "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-common.HasDataService.hasESData", + "id": "def-common.IIndexPatternFieldList.add", "type": "Function", "tags": [], - "label": "hasESData", - "description": [], + "label": "add", + "description": [ + "\nAdd field to field list." + ], "signature": [ - "() => Promise" + "(field: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.FieldSpec", + "text": "FieldSpec" + }, + ") => ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + } ], - "path": "src/plugins/data_views/common/types.ts", + "path": "src/plugins/data_views/common/fields/field_list.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.IIndexPatternFieldList.add.$1", + "type": "CompoundType", + "tags": [], + "label": "field", + "description": [ + "field spec to add field to list" + ], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.FieldSpec", + "text": "FieldSpec" + } + ], + "path": "src/plugins/data_views/common/fields/field_list.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [ + "data view field instance which was added to list" + ] + }, + { + "parentPluginId": "dataViews", + "id": "def-common.IIndexPatternFieldList.getAll", + "type": "Function", + "tags": [], + "label": "getAll", + "description": [ + "\nReturns fields as plain array of data view field instances." + ], + "signature": [ + "() => ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + }, + "[]" + ], + "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, "trackAdoption": false, "children": [], @@ -23584,91 +22905,155 @@ }, { "parentPluginId": "dataViews", - "id": "def-common.HasDataService.hasUserDataView", + "id": "def-common.IIndexPatternFieldList.getByName", "type": "Function", "tags": [], - "label": "hasUserDataView", - "description": [], + "label": "getByName", + "description": [ + "\nGet field by name. Optimized, uses map to find field." + ], "signature": [ - "() => Promise" + "(name: string) => ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + }, + " | undefined" + ], + "path": "src/plugins/data_views/common/fields/field_list.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.IIndexPatternFieldList.getByName.$1", + "type": "string", + "tags": [], + "label": "name", + "description": [ + "name of field to find" + ], + "signature": [ + "string" + ], + "path": "src/plugins/data_views/common/fields/field_list.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [ + "data view field instance if found, undefined otherwise" + ] + }, + { + "parentPluginId": "dataViews", + "id": "def-common.IIndexPatternFieldList.getByType", + "type": "Function", + "tags": [], + "label": "getByType", + "description": [ + "\nGet fields by field type. Optimized, uses map to find fields." + ], + "signature": [ + "(type: string) => ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + }, + "[]" + ], + "path": "src/plugins/data_views/common/fields/field_list.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.IIndexPatternFieldList.getByType.$1", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "type of field to find" + ], + "signature": [ + "string" + ], + "path": "src/plugins/data_views/common/fields/field_list.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] + "returnComment": [ + "array of data view field instances if found, empty array otherwise" + ] }, { "parentPluginId": "dataViews", - "id": "def-common.HasDataService.hasDataView", + "id": "def-common.IIndexPatternFieldList.remove", "type": "Function", "tags": [], - "label": "hasDataView", - "description": [], - "signature": [ - "() => Promise" + "label": "remove", + "description": [ + "\nRemove field from field list" ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.IDataViewsApiClient", - "type": "Interface", - "tags": [], - "label": "IDataViewsApiClient", - "description": [], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.IDataViewsApiClient.getFieldsForWildcard", - "type": "Function", - "tags": [], - "label": "getFieldsForWildcard", - "description": [], "signature": [ - "(options: ", + "(field: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.GetFieldsOptions", - "text": "GetFieldsOptions" + "section": "def-common.FieldSpec", + "text": "FieldSpec" }, - ") => Promise<", - "FieldsForWildcardResponse", - ">" + " | ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + }, + ") => void" ], - "path": "src/plugins/data_views/common/types.ts", + "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-common.IDataViewsApiClient.getFieldsForWildcard.$1", - "type": "Object", + "id": "def-common.IIndexPatternFieldList.remove.$1", + "type": "CompoundType", "tags": [], - "label": "options", - "description": [], + "label": "field", + "description": [ + "field for removal" + ], "signature": [ { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.GetFieldsOptions", - "text": "GetFieldsOptions" + "section": "def-common.FieldSpec", + "text": "FieldSpec" + }, + " | ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" } ], - "path": "src/plugins/data_views/common/types.ts", + "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -23678,65 +23063,33 @@ }, { "parentPluginId": "dataViews", - "id": "def-common.IDataViewsApiClient.hasUserDataView", + "id": "def-common.IIndexPatternFieldList.removeAll", "type": "Function", "tags": [], - "label": "hasUserDataView", - "description": [], + "label": "removeAll", + "description": [ + "\nRemove all fields from field list." + ], "signature": [ - "() => Promise" + "() => void" ], - "path": "src/plugins/data_views/common/types.ts", + "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, "trackAdoption": false, "children": [], "returnComment": [] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList", - "type": "Interface", - "tags": [], - "label": "IIndexPatternFieldList", - "description": [ - "\nInterface for data view field list which _extends_ the array class." - ], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.IIndexPatternFieldList", - "text": "IIndexPatternFieldList" - }, - " extends ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" }, - "[]" - ], - "path": "src/plugins/data_views/common/fields/field_list.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.add", + "id": "def-common.IIndexPatternFieldList.replaceAll", "type": "Function", "tags": [], - "label": "add", + "label": "replaceAll", "description": [ - "\nAdd field to field list." + "\nReplace all fields in field list with new fields." ], "signature": [ - "(field: ", + "(specs: ", { "pluginId": "dataViews", "scope": "common", @@ -23744,14 +23097,7 @@ "section": "def-common.FieldSpec", "text": "FieldSpec" }, - ") => ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" - } + "[]) => void" ], "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, @@ -23759,12 +23105,12 @@ "children": [ { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.add.$1", - "type": "CompoundType", + "id": "def-common.IIndexPatternFieldList.replaceAll.$1", + "type": "Array", "tags": [], - "label": "field", + "label": "specs", "description": [ - "field spec to add field to list" + "array of field specs to add to list" ], "signature": [ { @@ -23773,7 +23119,8 @@ "docId": "kibDataViewsPluginApi", "section": "def-common.FieldSpec", "text": "FieldSpec" - } + }, + "[]" ], "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, @@ -23781,55 +23128,78 @@ "isRequired": true } ], - "returnComment": [ - "data view field instance which was added to list" - ] + "returnComment": [] }, { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.getAll", + "id": "def-common.IIndexPatternFieldList.update", "type": "Function", "tags": [], - "label": "getAll", + "label": "update", "description": [ - "\nReturns fields as plain array of data view field instances." + "\nUpdate a field in the list" ], "signature": [ - "() => ", + "(field: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" + "section": "def-common.FieldSpec", + "text": "FieldSpec" }, - "[]" + ") => void" ], "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, "trackAdoption": false, - "children": [], + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.IIndexPatternFieldList.update.$1", + "type": "CompoundType", + "tags": [], + "label": "field", + "description": [ + "field spec to update" + ], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.FieldSpec", + "text": "FieldSpec" + } + ], + "path": "src/plugins/data_views/common/fields/field_list.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], "returnComment": [] }, { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.getByName", + "id": "def-common.IIndexPatternFieldList.toSpec", "type": "Function", - "tags": [], - "label": "getByName", + "tags": [ + "return" + ], + "label": "toSpec", "description": [ - "\nGet field by name. Optimized, uses map to find field." + "\nField list as field spec map by name" ], "signature": [ - "(name: string) => ", + "(options?: ToSpecOptions | undefined) => ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" - }, - " | undefined" + "section": "def-common.DataViewFieldMap", + "text": "DataViewFieldMap" + } ], "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, @@ -23837,131 +23207,205 @@ "children": [ { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.getByName.$1", - "type": "string", + "id": "def-common.IIndexPatternFieldList.toSpec.$1", + "type": "Object", "tags": [], - "label": "name", + "label": "options", "description": [ - "name of field to find" + "optionally provide a function to get field formatter for fields" ], "signature": [ - "string" + "ToSpecOptions | undefined" ], "path": "src/plugins/data_views/common/fields/field_list.ts", "deprecated": false, "trackAdoption": false, - "isRequired": true + "isRequired": false } ], - "returnComment": [ - "data view field instance if found, undefined otherwise" - ] + "returnComment": [ + "map of field specs by name" + ] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.IndexPatternExpressionType", + "type": "Interface", + "tags": [], + "label": "IndexPatternExpressionType", + "description": [ + "\nIndex pattern expression interface" + ], + "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.IndexPatternExpressionType.type", + "type": "string", + "tags": [], + "label": "type", + "description": [ + "\nExpression type" + ], + "signature": [ + "\"index_pattern\"" + ], + "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts", + "deprecated": false, + "trackAdoption": false }, { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.getByType", - "type": "Function", + "id": "def-common.IndexPatternExpressionType.value", + "type": "Object", "tags": [], - "label": "getByType", + "label": "value", "description": [ - "\nGet fields by field type. Optimized, uses map to find fields." + "\nValue - DataViewSpec" ], "signature": [ - "(type: string) => ", + "{ id?: string | undefined; version?: string | undefined; title?: string | undefined; timeFieldName?: string | undefined; sourceFilters?: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" + "section": "def-common.SourceFilter", + "text": "SourceFilter" }, - "[]" - ], - "path": "src/plugins/data_views/common/fields/field_list.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ + "[] | undefined; fields?: ", { - "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.getByType.$1", - "type": "string", - "tags": [], - "label": "type", - "description": [ - "type of field to find" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/fields/field_list.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewFieldMap", + "text": "DataViewFieldMap" + }, + " | undefined; typeMeta?: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.TypeMeta", + "text": "TypeMeta" + }, + " | undefined; type?: string | undefined; fieldFormats?: Record> | undefined; runtimeFieldMap?: Record | undefined; fieldAttrs?: ", + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.FieldAttrs", + "text": "FieldAttrs" + }, + " | undefined; allowNoIndex?: boolean | undefined; namespaces?: string[] | undefined; name?: string | undefined; }" ], - "returnComment": [ - "array of data view field instances if found, empty array otherwise" - ] - }, + "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.PersistenceAPI", + "type": "Interface", + "tags": [], + "label": "PersistenceAPI", + "description": [ + "\nCommon interface for the saved objects client on server and content management in browser" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.remove", + "id": "def-common.PersistenceAPI.find", "type": "Function", "tags": [], - "label": "remove", + "label": "find", "description": [ - "\nRemove field from field list" + "\nSearch for saved objects" ], "signature": [ - "(field: ", + "(options: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldSpec", - "text": "FieldSpec" + "section": "def-common.SavedObjectsClientCommonFindArgs", + "text": "SavedObjectsClientCommonFindArgs" }, - " | ", + ") => Promise<", + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObject", + "text": "SavedObject" + }, + "<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" + "section": "def-common.DataViewAttributes", + "text": "DataViewAttributes" }, - ") => void" + ">[]>" ], - "path": "src/plugins/data_views/common/fields/field_list.ts", + "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.remove.$1", - "type": "CompoundType", + "id": "def-common.PersistenceAPI.find.$1", + "type": "Object", "tags": [], - "label": "field", + "label": "options", "description": [ - "field for removal" + "- options for search" ], "signature": [ { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldSpec", - "text": "FieldSpec" - }, - " | ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" + "section": "def-common.SavedObjectsClientCommonFindArgs", + "text": "SavedObjectsClientCommonFindArgs" } ], - "path": "src/plugins/data_views/common/fields/field_list.ts", + "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -23971,66 +23415,49 @@ }, { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.removeAll", - "type": "Function", - "tags": [], - "label": "removeAll", - "description": [ - "\nRemove all fields from field list." - ], - "signature": [ - "() => void" - ], - "path": "src/plugins/data_views/common/fields/field_list.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.replaceAll", + "id": "def-common.PersistenceAPI.get", "type": "Function", "tags": [], - "label": "replaceAll", + "label": "get", "description": [ - "\nReplace all fields in field list with new fields." + "\nGet a single saved object by id" ], "signature": [ - "(specs: ", + "(id: string) => Promise<", + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObject", + "text": "SavedObject" + }, + "<", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldSpec", - "text": "FieldSpec" + "section": "def-common.DataViewAttributes", + "text": "DataViewAttributes" }, - "[]) => void" + ">>" ], - "path": "src/plugins/data_views/common/fields/field_list.ts", + "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.replaceAll.$1", - "type": "Array", + "id": "def-common.PersistenceAPI.get.$1", + "type": "string", "tags": [], - "label": "specs", + "label": "id", "description": [ - "array of field specs to add to list" + "- id of saved object" ], "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldSpec", - "text": "FieldSpec" - }, - "[]" + "string" ], - "path": "src/plugins/data_views/common/fields/field_list.ts", + "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -24040,204 +23467,254 @@ }, { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.update", + "id": "def-common.PersistenceAPI.update", "type": "Function", "tags": [], "label": "update", "description": [ - "\nUpdate a field in the list" + "\nUpdate a saved object by id" ], "signature": [ - "(field: ", + "(id: string, attributes: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldSpec", - "text": "FieldSpec" + "section": "def-common.DataViewAttributes", + "text": "DataViewAttributes" }, - ") => void" + ", options: { version?: string | undefined; }) => Promise<", + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObject", + "text": "SavedObject" + }, + ">" ], - "path": "src/plugins/data_views/common/fields/field_list.ts", + "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.update.$1", - "type": "CompoundType", + "id": "def-common.PersistenceAPI.update.$1", + "type": "string", "tags": [], - "label": "field", + "label": "id", "description": [ - "field spec to update" + "- id of saved object" + ], + "signature": [ + "string" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "dataViews", + "id": "def-common.PersistenceAPI.update.$2", + "type": "Object", + "tags": [], + "label": "attributes", + "description": [ + "- attributes to update" ], "signature": [ { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldSpec", - "text": "FieldSpec" + "section": "def-common.DataViewAttributes", + "text": "DataViewAttributes" } ], - "path": "src/plugins/data_views/common/fields/field_list.ts", + "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "dataViews", + "id": "def-common.PersistenceAPI.update.$3", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.PersistenceAPI.update.$3.version", + "type": "string", + "tags": [], + "label": "version", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] } ], "returnComment": [] }, { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.toSpec", + "id": "def-common.PersistenceAPI.create", "type": "Function", - "tags": [ - "return" - ], - "label": "toSpec", + "tags": [], + "label": "create", "description": [ - "\nField list as field spec map by name" + "\nCreate a saved object" ], "signature": [ - "(options?: ToSpecOptions | undefined) => ", + "(attributes: ", { "pluginId": "dataViews", "scope": "common", "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewFieldMap", - "text": "DataViewFieldMap" - } + "section": "def-common.DataViewAttributes", + "text": "DataViewAttributes" + }, + ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; overwrite?: boolean | undefined; }) => Promise<", + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObject", + "text": "SavedObject" + }, + ">" ], - "path": "src/plugins/data_views/common/fields/field_list.ts", + "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "dataViews", - "id": "def-common.IIndexPatternFieldList.toSpec.$1", + "id": "def-common.PersistenceAPI.create.$1", "type": "Object", "tags": [], - "label": "options", + "label": "attributes", "description": [ - "optionally provide a function to get field formatter for fields" + "- attributes to set" ], "signature": [ - "ToSpecOptions | undefined" + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewAttributes", + "text": "DataViewAttributes" + } ], - "path": "src/plugins/data_views/common/fields/field_list.ts", + "path": "src/plugins/data_views/common/types.ts", "deprecated": false, "trackAdoption": false, - "isRequired": false + "isRequired": true + }, + { + "parentPluginId": "dataViews", + "id": "def-common.PersistenceAPI.create.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.PersistenceAPI.create.$2.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.PersistenceAPI.create.$2.initialNamespaces", + "type": "Array", + "tags": [], + "label": "initialNamespaces", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.PersistenceAPI.create.$2.overwrite", + "type": "CompoundType", + "tags": [], + "label": "overwrite", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] } ], - "returnComment": [ - "map of field specs by name" - ] - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.IndexPatternExpressionType", - "type": "Interface", - "tags": [], - "label": "IndexPatternExpressionType", - "description": [ - "\nIndex pattern expression interface" - ], - "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ + "returnComment": [] + }, { "parentPluginId": "dataViews", - "id": "def-common.IndexPatternExpressionType.type", - "type": "string", + "id": "def-common.PersistenceAPI.delete", + "type": "Function", "tags": [], - "label": "type", + "label": "delete", "description": [ - "\nExpression type" + "\nDelete a saved object by id" ], "signature": [ - "\"index_pattern\"" + "(id: string) => Promise" ], - "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts", + "path": "src/plugins/data_views/common/types.ts", "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.IndexPatternExpressionType.value", - "type": "Object", - "tags": [], - "label": "value", - "description": [ - "\nValue - DataViewSpec" - ], - "signature": [ - "{ id?: string | undefined; version?: string | undefined; title?: string | undefined; timeFieldName?: string | undefined; sourceFilters?: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.SourceFilter", - "text": "SourceFilter" - }, - "[] | undefined; fields?: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewFieldMap", - "text": "DataViewFieldMap" - }, - " | undefined; typeMeta?: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.TypeMeta", - "text": "TypeMeta" - }, - " | undefined; type?: string | undefined; fieldFormats?: Record> | undefined; runtimeFieldMap?: Record | undefined; fieldAttrs?: ", + "trackAdoption": false, + "children": [ { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.FieldAttrs", - "text": "FieldAttrs" - }, - " | undefined; allowNoIndex?: boolean | undefined; namespaces?: string[] | undefined; name?: string | undefined; }" + "parentPluginId": "dataViews", + "id": "def-common.PersistenceAPI.delete.$1", + "type": "string", + "tags": [], + "label": "id", + "description": [ + "- id of saved object" + ], + "signature": [ + "string" + ], + "path": "src/plugins/data_views/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } ], - "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts", - "deprecated": false, - "trackAdoption": false + "returnComment": [] } ], "initialIsOpen": false @@ -24760,509 +24237,80 @@ "id": "def-common.SavedObject.coreMigrationVersion", "type": "string", "tags": [], - "label": "coreMigrationVersion", - "description": [ - "A semver value that is used when upgrading objects between Kibana versions." - ], - "signature": [ - "string | undefined" - ], - "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObject.typeMigrationVersion", - "type": "string", - "tags": [], - "label": "typeMigrationVersion", - "description": [ - "A semver value that is used when migrating documents between Kibana versions." - ], - "signature": [ - "string | undefined" - ], - "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObject.namespaces", - "type": "Array", - "tags": [], - "label": "namespaces", - "description": [ - "\nSpace(s) that this saved object exists in. This attribute is not used for \"global\" saved object types which are registered with\n`namespaceType: 'agnostic'`." - ], - "signature": [ - "string[] | undefined" - ], - "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObject.originId", - "type": "string", - "tags": [], - "label": "originId", - "description": [ - "\nThe ID of the saved object this originated from. This is set if this object's `id` was regenerated; that can happen during migration\nfrom a legacy single-namespace type, or during import. It is only set during migration or create operations. This is used during import\nto ensure that ID regeneration is deterministic, so saved objects will be overwritten if they are imported multiple times into a given\nspace." - ], - "signature": [ - "string | undefined" - ], - "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObject.managed", - "type": "CompoundType", - "tags": [], - "label": "managed", - "description": [ - "\nFlag indicating if a saved object is managed by Kibana (default=false)\n\nThis can be leveraged by applications to e.g. prevent edits to a managed\nsaved object. Instead, users can be guided to create a copy first and\nmake their edits to the copy." - ], - "signature": [ - "boolean | undefined" - ], - "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon", - "type": "Interface", - "tags": [], - "label": "SavedObjectsClientCommon", - "description": [ - "\nCommon interface for the saved objects client" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.find", - "type": "Function", - "tags": [], - "label": "find", - "description": [ - "\nSearch for saved objects" - ], - "signature": [ - "(options: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.SavedObjectsClientCommonFindArgs", - "text": "SavedObjectsClientCommonFindArgs" - }, - ") => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - "<", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ">[]>" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.find.$1", - "type": "Object", - "tags": [], - "label": "options", - "description": [ - "- options for search" - ], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.SavedObjectsClientCommonFindArgs", - "text": "SavedObjectsClientCommonFindArgs" - } - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.get", - "type": "Function", - "tags": [], - "label": "get", - "description": [ - "\nGet a single saved object by id" - ], - "signature": [ - "(id: string) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - "<", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ">>" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.get.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- id of saved object" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.getSavedSearch", - "type": "Function", - "tags": [], - "label": "getSavedSearch", - "description": [ - "\nUpdate a saved object by id" - ], - "signature": [ - "(id: string) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - ">" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.getSavedSearch.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- id of saved object" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } + "label": "coreMigrationVersion", + "description": [ + "A semver value that is used when upgrading objects between Kibana versions." ], - "returnComment": [] + "signature": [ + "string | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", + "deprecated": false, + "trackAdoption": false }, { "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.update", - "type": "Function", + "id": "def-common.SavedObject.typeMigrationVersion", + "type": "string", "tags": [], - "label": "update", + "label": "typeMigrationVersion", "description": [ - "\nUpdate a saved object by id" + "A semver value that is used when migrating documents between Kibana versions." ], "signature": [ - "(id: string, attributes: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ", options: { version?: string | undefined; }) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - ">" + "string | undefined" ], - "path": "src/plugins/data_views/common/types.ts", + "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.update.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- id of saved object" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.update.$2", - "type": "Object", - "tags": [], - "label": "attributes", - "description": [ - "- attributes to update" - ], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - } - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.update.$3", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.update.$3.version", - "type": "string", - "tags": [], - "label": "version", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false - } - ] - } - ], - "returnComment": [] + "trackAdoption": false }, { "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.create", - "type": "Function", + "id": "def-common.SavedObject.namespaces", + "type": "Array", "tags": [], - "label": "create", + "label": "namespaces", "description": [ - "\nCreate a saved object" + "\nSpace(s) that this saved object exists in. This attribute is not used for \"global\" saved object types which are registered with\n`namespaceType: 'agnostic'`." ], "signature": [ - "(attributes: ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - }, - ", options: { id?: string | undefined; initialNamespaces?: string[] | undefined; overwrite?: boolean | undefined; }) => Promise<", - { - "pluginId": "@kbn/core-saved-objects-common", - "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" - }, - ">" + "string[] | undefined" ], - "path": "src/plugins/data_views/common/types.ts", + "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.create.$1", - "type": "Object", - "tags": [], - "label": "attributes", - "description": [ - "- attributes to set" - ], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewAttributes", - "text": "DataViewAttributes" - } - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.create.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.create.$2.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.create.$2.initialNamespaces", - "type": "Array", - "tags": [], - "label": "initialNamespaces", - "description": [], - "signature": [ - "string[] | undefined" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.create.$2.overwrite", - "type": "CompoundType", - "tags": [], - "label": "overwrite", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false - } - ] - } - ], - "returnComment": [] + "trackAdoption": false }, { "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.delete", - "type": "Function", + "id": "def-common.SavedObject.originId", + "type": "string", "tags": [], - "label": "delete", + "label": "originId", "description": [ - "\nDelete a saved object by id" + "\nThe ID of the saved object this originated from. This is set if this object's `id` was regenerated; that can happen during migration\nfrom a legacy single-namespace type, or during import. It is only set during migration or create operations. This is used during import\nto ensure that ID regeneration is deterministic, so saved objects will be overwritten if they are imported multiple times into a given\nspace." ], "signature": [ - "(id: string) => Promise" + "string | undefined" ], - "path": "src/plugins/data_views/common/types.ts", + "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "dataViews", - "id": "def-common.SavedObjectsClientCommon.delete.$1", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "- id of saved object" - ], - "signature": [ - "string" - ], - "path": "src/plugins/data_views/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } + "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-common.SavedObject.managed", + "type": "CompoundType", + "tags": [], + "label": "managed", + "description": [ + "\nFlag indicating if a saved object is managed by Kibana (default=false)\n\nThis can be leveraged by applications to e.g. prevent edits to a managed\nsaved object. Instead, users can be guided to create a copy first and\nmake their edits to the copy." ], - "returnComment": [] + "signature": [ + "boolean | undefined" + ], + "path": "packages/core/saved-objects/core-saved-objects-common/src/server_types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index d9b62550be526..e4fe9a051c9e4 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1052 | 0 | 268 | 2 | +| 1009 | 0 | 243 | 2 | ## Client diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 89d7ff533e308..ca4cf96b7503f 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index ac0366858ba50..f8cf8ffbe522b 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,10 +21,10 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | stackAlerts, alerting, securitySolution, inputControlVis | - | | | stackAlerts, infra, graph, inputControlVis, securitySolution, savedObjects | - | | | dashboard, stackAlerts, dataVisualizer, expressionPartitionVis | - | -| | @kbn/es-query, visualizationUiComponents, observability, securitySolution, timelines, lists, threatIntelligence, dataViews, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, eventAnnotation, lens, aiops, ml, logsShared, visTypeTimeseries, apm, triggersActionsUi, exploratoryView, stackAlerts, fleet, dataVisualizer, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | +| | @kbn/es-query, visualizationUiComponents, observability, securitySolution, timelines, lists, threatIntelligence, savedSearch, dataViews, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, eventAnnotation, lens, aiops, ml, logsShared, visTypeTimeseries, apm, triggersActionsUi, exploratoryView, stackAlerts, fleet, dataVisualizer, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | | | stackAlerts, alerting, securitySolution, inputControlVis | - | -| | @kbn/es-query, visualizationUiComponents, observability, securitySolution, timelines, lists, threatIntelligence, dataViews, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, eventAnnotation, lens, aiops, ml, logsShared, visTypeTimeseries, apm, triggersActionsUi, exploratoryView, stackAlerts, fleet, dataVisualizer, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | -| | @kbn/es-query, visualizationUiComponents, observability, securitySolution, timelines, lists, threatIntelligence, data, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, eventAnnotation, lens, aiops, ml, logsShared, visTypeTimeseries, apm, triggersActionsUi, exploratoryView, stackAlerts, fleet, dataVisualizer, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega | - | +| | @kbn/es-query, visualizationUiComponents, observability, securitySolution, timelines, lists, threatIntelligence, savedSearch, dataViews, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, eventAnnotation, lens, aiops, ml, logsShared, visTypeTimeseries, apm, triggersActionsUi, exploratoryView, stackAlerts, fleet, dataVisualizer, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | +| | @kbn/es-query, visualizationUiComponents, observability, securitySolution, timelines, lists, threatIntelligence, savedSearch, data, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, eventAnnotation, lens, aiops, ml, logsShared, visTypeTimeseries, apm, triggersActionsUi, exploratoryView, stackAlerts, fleet, dataVisualizer, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega | - | | | home, data, esUiShared, savedObjectsManagement, exploratoryView, fleet, observability, ml, apm, indexLifecycleManagement, observabilityOnboarding, synthetics, upgradeAssistant, uptime, ux, kibanaOverview | - | | | encryptedSavedObjects, actions, data, ml, logstash, securitySolution, cloudChat | - | | | actions, ml, savedObjectsTagging, enterpriseSearch | - | @@ -59,12 +59,12 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | securitySolution | - | | | securitySolution | - | | | exploratoryView, fleet, dataVisualizer, cloudSecurityPosture, discoverEnhanced, osquery, synthetics | - | -| | @kbn/core-plugins-browser-internal, @kbn/core-root-browser-internal, dataViews, home, data, savedObjects, unifiedSearch, presentationUtil, visualizations, dashboard, lens, fileUpload, dashboardEnhanced, transform, discover, dataVisualizer | - | +| | @kbn/core-plugins-browser-internal, @kbn/core-root-browser-internal, home, savedObjects, unifiedSearch, presentationUtil, visualizations, dashboard, fileUpload, dashboardEnhanced, transform, discover, dataVisualizer | - | | | @kbn/core-lifecycle-browser, @kbn/core-saved-objects-browser-internal, @kbn/core, visualizations, dashboard, exploratoryView, transform, @kbn/core-saved-objects-browser-mocks | - | | | actions, alerting | - | | | discover | - | | | data, discover, imageEmbeddable, embeddable | - | -| | @kbn/core-saved-objects-browser-mocks, dataViews, discover, @kbn/core-saved-objects-browser-internal | - | +| | @kbn/core-saved-objects-browser-mocks, discover, @kbn/core-saved-objects-browser-internal | - | | | advancedSettings, discover | - | | | @kbn/core-saved-objects-browser, @kbn/core-saved-objects-browser-internal, @kbn/core, dataViews, home, savedObjects, visualizations, lens, visTypeTimeseries, @kbn/core-saved-objects-browser-mocks | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, savedObjects, dashboard | - | @@ -107,7 +107,6 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | dataViews, maps | - | | | dataViewManagement, dataViews | - | | | dataViews, dataViewManagement | - | -| | @kbn/core-lifecycle-browser-mocks, @kbn/core, dataViews, @kbn/core-plugins-browser-internal | - | | | spaces, savedObjectsManagement | - | | | unifiedSearch | - | | | unifiedSearch | - | @@ -133,6 +132,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | @kbn/content-management-table-list-view, filesManagement | - | | | @kbn/core | - | | | @kbn/core | - | +| | @kbn/core-lifecycle-browser-mocks, @kbn/core, @kbn/core-plugins-browser-internal | - | | | @kbn/core | - | | | @kbn/core-elasticsearch-server-internal, @kbn/core-plugins-server-internal, console | - | | | @kbn/core-plugins-server-internal | - | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 2aeacff8ffd21..83536ed983ed0 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -343,7 +343,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/plugin.ts#:~:text=authc) | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/plugin.ts#:~:text=authz) | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/plugin.ts#:~:text=index) | - | -| | [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/types.ts#:~:text=SavedObjectAttributes), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/types.ts#:~:text=SavedObjectAttributes), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/types.ts#:~:text=SavedObjectAttributes)+ 16 more | - | +| | [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [actions_client.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/actions_client.ts#:~:text=SavedObjectAttributes), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/types.ts#:~:text=SavedObjectAttributes), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/types.ts#:~:text=SavedObjectAttributes), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/types.ts#:~:text=SavedObjectAttributes)+ 10 more | - | | | [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/saved_objects/index.ts#:~:text=convertToMultiNamespaceTypeVersion), [index.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/actions/server/saved_objects/index.ts#:~:text=convertToMultiNamespaceTypeVersion) | - | @@ -514,15 +514,14 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.test.ts#:~:text=title), [inspector_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inspect/inspector_stats.ts#:~:text=title), [response_writer.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/tabify/response_writer.ts#:~:text=title), [field.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=title), [get_display_value.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts#:~:text=title), [painless_error.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/errors/painless_error.tsx#:~:text=title), [agg_config.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=title), [_terms_other_bucket_helper.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts#:~:text=title)+ 6 more | - | -| | [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.test.ts#:~:text=title), [inspector_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inspect/inspector_stats.ts#:~:text=title), [response_writer.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/tabify/response_writer.ts#:~:text=title), [field.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=title), [get_display_value.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts#:~:text=title), [painless_error.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/errors/painless_error.tsx#:~:text=title), [agg_config.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=title), [_terms_other_bucket_helper.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts#:~:text=title)+ 6 more | - | -| | [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.test.ts#:~:text=title), [inspector_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inspect/inspector_stats.ts#:~:text=title), [response_writer.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/tabify/response_writer.ts#:~:text=title), [field.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=title), [get_display_value.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts#:~:text=title), [painless_error.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/errors/painless_error.tsx#:~:text=title), [agg_config.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=title), [_terms_other_bucket_helper.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts#:~:text=title)+ 6 more | - | +| | [inspector_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inspect/inspector_stats.ts#:~:text=title), [response_writer.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/tabify/response_writer.ts#:~:text=title), [field.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=title), [get_display_value.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts#:~:text=title), [painless_error.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/errors/painless_error.tsx#:~:text=title), [agg_config.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=title), [_terms_other_bucket_helper.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts#:~:text=title), [multi_terms.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/multi_terms.test.ts#:~:text=title), [multi_terms.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/multi_terms.test.ts#:~:text=title), [rare_terms.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/rare_terms.test.ts#:~:text=title)+ 3 more | - | +| | [inspector_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inspect/inspector_stats.ts#:~:text=title), [response_writer.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/tabify/response_writer.ts#:~:text=title), [field.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=title), [get_display_value.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts#:~:text=title), [painless_error.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/errors/painless_error.tsx#:~:text=title), [agg_config.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=title), [_terms_other_bucket_helper.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts#:~:text=title), [multi_terms.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/multi_terms.test.ts#:~:text=title), [multi_terms.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/multi_terms.test.ts#:~:text=title), [rare_terms.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/rare_terms.test.ts#:~:text=title)+ 3 more | - | +| | [inspector_stats.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inspect/inspector_stats.ts#:~:text=title), [response_writer.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/tabify/response_writer.ts#:~:text=title), [field.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/param_types/field.ts#:~:text=title), [get_display_value.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/query/filter_manager/lib/get_display_value.ts#:~:text=title), [painless_error.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/errors/painless_error.tsx#:~:text=title), [agg_config.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=title), [_terms_other_bucket_helper.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts#:~:text=title), [multi_terms.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/multi_terms.test.ts#:~:text=title), [multi_terms.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/multi_terms.test.ts#:~:text=title), [rare_terms.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/aggs/buckets/rare_terms.test.ts#:~:text=title)+ 3 more | - | | | [get_columns.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [get_columns.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [get_columns.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks) | - | | | [session_service.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/session/session_service.ts#:~:text=authc) | - | | | [data_table.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx#:~:text=executeTriggerActions), [data_table.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx#:~:text=executeTriggerActions) | - | -| | [kibana_context.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/expressions/kibana_context.ts#:~:text=savedObjects) | - | | | [api.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject)+ 2 more | - | -| | [kibana_context.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.ts#:~:text=SavedObjectReference), [kibana_context.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/expressions/kibana_context.ts#:~:text=SavedObjectReference), [extract_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/extract_references.ts#:~:text=SavedObjectReference), [extract_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/extract_references.ts#:~:text=SavedObjectReference), [extract_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/extract_references.ts#:~:text=SavedObjectReference), [inject_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inject_references.ts#:~:text=SavedObjectReference), [inject_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inject_references.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference)+ 5 more | - | +| | [extract_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/extract_references.ts#:~:text=SavedObjectReference), [extract_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/extract_references.ts#:~:text=SavedObjectReference), [extract_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/extract_references.ts#:~:text=SavedObjectReference), [inject_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inject_references.ts#:~:text=SavedObjectReference), [inject_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inject_references.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/persistable_state.ts#:~:text=SavedObjectReference)+ 3 more | - | | | [query.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/saved_objects/query.ts#:~:text=convertToMultiNamespaceTypeVersion) | - | @@ -560,11 +559,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=removeScriptedField) | - | | | [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getNonScriptedFields) | - | | | [data_view.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.ts#:~:text=getScriptedFields), [data_view.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.ts#:~:text=getScriptedFields), [data_views.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_views.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields) | - | -| | [plugin.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/public/plugin.ts#:~:text=savedObjects) | - | -| | [get_title.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/lib/get_title.ts#:~:text=SavedObjectsClientContract), [get_title.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/lib/get_title.ts#:~:text=SavedObjectsClientContract), [saved_objects_client_wrapper.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/public/saved_objects_client_wrapper.ts#:~:text=SavedObjectsClientContract), [saved_objects_client_wrapper.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/public/saved_objects_client_wrapper.ts#:~:text=SavedObjectsClientContract) | - | +| | [get_title.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/lib/get_title.ts#:~:text=SavedObjectsClientContract), [get_title.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/lib/get_title.ts#:~:text=SavedObjectsClientContract) | - | | | [get_title.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/lib/get_title.ts#:~:text=get) | - | -| | [saved_objects_client_wrapper.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/public/saved_objects_client_wrapper.ts#:~:text=resolve) | - | -| | [saved_objects_client_wrapper.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/public/saved_objects_client_wrapper.test.ts#:~:text=savedObjectsServiceMock), [saved_objects_client_wrapper.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/public/saved_objects_client_wrapper.test.ts#:~:text=savedObjectsServiceMock) | - | | | [load_index_pattern.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/expressions/load_index_pattern.ts#:~:text=SavedObjectReference), [load_index_pattern.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/expressions/load_index_pattern.ts#:~:text=SavedObjectReference), [persistable_state.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/persistable_state.test.ts#:~:text=SavedObjectReference), [persistable_state.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/persistable_state.test.ts#:~:text=SavedObjectReference) | - | | | [data_views.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/server/saved_objects/data_views.ts#:~:text=convertToMultiNamespaceTypeVersion) | - | @@ -839,7 +835,6 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/data_views_service/loader.ts#:~:text=title), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=title), [loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/data_views_service/loader.ts#:~:text=title), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=title) | - | | | [loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/data_views_service/loader.ts#:~:text=title), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=title) | - | | | [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=SavedObjectSaveModal), [save_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/annotations/actions/save_action.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | -| | [form_based.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx#:~:text=savedObjects), [form_based.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx#:~:text=savedObjects), [visualization.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx#:~:text=savedObjects), [visualization.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx#:~:text=savedObjects), [visualization.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx#:~:text=savedObjects) | - | | | [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SavedObjectsClientContract), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SavedObjectsClientContract), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SavedObjectsClientContract) | - | | | [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SimpleSavedObject), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/persistence/saved_objects_utils/find_object_by_title.test.ts#:~:text=SimpleSavedObject) | - | | | [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/types.ts#:~:text=ResolvedSimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/types.ts#:~:text=ResolvedSimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/types.ts#:~:text=ResolvedSimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/lens/public/types.ts#:~:text=ResolvedSimpleSavedObject) | - | @@ -1105,6 +1100,9 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title) | - | +| | [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title) | - | +| | [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title), [kibana_context.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/common/expressions/kibana_context.test.ts#:~:text=title) | - | | | [types.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/public/services/saved_searches/types.ts#:~:text=ResolvedSimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/public/services/saved_searches/types.ts#:~:text=ResolvedSimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/public/services/saved_searches/types.ts#:~:text=ResolvedSimpleSavedObject), [types.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/public/services/saved_searches/types.ts#:~:text=ResolvedSimpleSavedObject) | - | | | [search_migrations.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/server/saved_objects/search_migrations.ts#:~:text=SavedObjectAttributes), [search_migrations.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/server/saved_objects/search_migrations.ts#:~:text=SavedObjectAttributes), [search_migrations.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/server/saved_objects/search_migrations.ts#:~:text=SavedObjectAttributes), [search_migrations.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/server/saved_objects/search_migrations.ts#:~:text=SavedObjectAttributes) | - | | | [search.ts](https://github.com/elastic/kibana/tree/main/src/plugins/saved_search/server/saved_objects/search.ts#:~:text=convertToMultiNamespaceTypeVersion) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 8689e545b3cca..e096bc42395d4 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.devdocs.json b/api_docs/dev_tools.devdocs.json index f91298e51f8e0..624340d7d5db6 100644 --- a/api_docs/dev_tools.devdocs.json +++ b/api_docs/dev_tools.devdocs.json @@ -39,6 +39,47 @@ "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "devTools", + "id": "def-public.DevToolsPlugin.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "src/plugins/dev_tools/public/plugin.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "devTools", + "id": "def-public.DevToolsPlugin.Unnamed.$1", + "type": "Object", + "tags": [], + "label": "initializerContext", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-plugins-browser", + "scope": "common", + "docId": "kibKbnCorePluginsBrowserPluginApi", + "section": "def-common.PluginInitializerContext", + "text": "PluginInitializerContext" + }, + "<", + "ConfigSchema", + ">" + ], + "path": "src/plugins/dev_tools/public/plugin.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, { "parentPluginId": "devTools", "id": "def-public.DevToolsPlugin.setup", diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index de57ebf6f2fd6..d0290715c0f57 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/platform-deployment-management](https://github.com/orgs/elasti | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 10 | 0 | 8 | 2 | +| 12 | 0 | 10 | 3 | ## Client diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index cab341794c4c9..4a80c4c6ec659 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index d6819707fadcc..bf5d24a0bc322 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 92f3a92f8bd1e..828b0e4f1e0d4 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index a8c8947d8b1d4..1f61f06f10b54 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index d72b3de2dd500..3306b885aba81 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index e9e842edb8049..ecf23355c6f43 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 27a73b03bb915..79d6bf3e05471 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index f7f0070975dfa..0b5b81b8a877d 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 61f2798f10136..9bb15b0f32bfa 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 015b2f5a0e2b3..13d89a9e5c378 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index 32b8b0950d16d..12961303978f4 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index a4a062cccb671..fb0b8ee37a743 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 1d33f8ceac555..d9c36252d16aa 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index b2306563333ea..f1fb11d646678 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 13dfbefdbaee7..00bed41e99c19 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 3feab5abbcd85..89af764aa6440 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 6ae6db0295e11..c75de62e3dbcf 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index de3837197abef..289424f4e8834 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index d959120a0042d..cd0da75ef6e8c 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 2e7257b808542..43d6601702c5a 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index c4457a2fdd9bc..ccb5a2aedf6b2 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 8642683a37566..87d7897eb200d 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index b50fef7fefa7f..16bccdb267bd2 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index bbbef3ab4dc83..74d25081b5d1d 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 155d195e9798f..f3f58b2a27a3e 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 115d1cd1fcc91..41fd3419f5de7 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index f609628caf1ce..c63612795faac 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 9eafe929bc379..542d4ed08c338 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index d4a2511dbab7d..1ddacd877c509 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index 9de168b7d8328..954bde0d1ae86 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 41676ba91ebd5..ee043ce78284d 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 7bff641eb6b85..0e1917e4dfc2e 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 901e1e9567eef..e68c91fe3785f 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index da6bc802b7bb1..00c3488be64b6 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index c6566bbdcc35c..5109497abe2a6 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 4599f4d91be12..5473efb3ca053 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 5699de544a103..47fa332ba3a94 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 760ccd7178ea3..9475dc7e3aa86 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 8153485f0a978..a329af66d5229 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index b509edb9980e4..c3528e6d07eec 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 6a341ea8de7cb..130d069ce98f9 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 9220c5b3e06cf..f7d908b6ecdc9 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 2b30373afae97..2dea9f2aa6f6b 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index c5b248d6fa5db..39705e2c53c6b 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 5c7ac9307e0ce..b2916aac20659 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 1dbb99178a4eb..909956bbee755 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 87e320d73c510..36510a7c30fca 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 88daec8df1800..84d0e52258020 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index dee6831b03478..00fcd4d59e31c 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index a22fbc1a97192..8cdfd63966f52 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 153803d18e107..9ea23175e6de5 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index a7b26d8831dee..73baa1123393d 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 2f738230e2fe7..9978be994a024 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 3f39206b8ab29..c2fc51e9d93fc 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index f34c8cb6c31c8..0d676f679653d 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index b3970ea1f7421..37f318fe7ef19 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index d2d22a231df4c..6ae83a48eccc5 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index be99d7e5b2848..fcb1aac9ea596 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 8aa2d1142a8e6..568f91c78e9ed 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index e11cbfaa4b184..ba2472670cd1e 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index 5652223e5d4dc..2985544798bfa 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 617ed017c7736..e1b6a605379ec 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 6dbfa8bebf27c..d98c2ec0ef6ea 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index c0eef44adb21b..168bb6090af47 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 3b4640cd2e0ce..53d8ef0f3bc6d 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index dbbd31a3faf88..fd8f651f682ad 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index a00c0a06eece2..4b2c661c20cb7 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index a04bf47255354..5331221829399 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 3af51b4d3516b..0eaf6c9da09ec 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index ef6cf90a4c47a..56f814d71e837 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index e2b9319fbf1e2..0475270a89c9c 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 73e757324d686..30a71e5a065c2 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index b0b3ac6a8deac..362b437d4571f 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index ccbc97ae4cff7..48d8865d9f46d 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index c6b8f98b0f3b0..7df7bbf4623f3 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.devdocs.json b/api_docs/kbn_content_management_table_list_view_table.devdocs.json index 246c8321c04a3..35d5364d4b7d2 100644 --- a/api_docs/kbn_content_management_table_list_view_table.devdocs.json +++ b/api_docs/kbn_content_management_table_list_view_table.devdocs.json @@ -223,7 +223,9 @@ "section": "def-common.OverlayRef", "text": "OverlayRef" }, - "; }; }" + "; }; theme: { theme$: ", + "Observable", + "<{ readonly darkMode: boolean; }>; }; }" ], "path": "packages/content-management/table_list_view_table/src/services.tsx", "deprecated": false, diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 607e375251046..b50777fa84f3f 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 3cce1633db84c..91f3c5d1783fd 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 2851fce8bb011..6847b4d1aa9c5 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index e129f9e026241..173935358b865 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 5b7e9688c2523..8f30a416545c9 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 323e0178add9a..dcb36cb93ed9a 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 4579c9ab0cf27..e43811ca0ad9b 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index d78792acbb6d3..ee34b37d18ebf 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index cba813e03b4f9..af1abb215ef59 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 7b396da390f58..66115be3595c8 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 86833f452c101..450d8f94b3d4e 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 1d755c713d67f..d771c1444b659 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index b1d6ec59361fa..5639638acd338 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index ea1c59c881a9b..da1a800000ea9 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index 41c398c5e707f..16014275cde75 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 0ede34dc1c34d..3c69264a4447e 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 865e118592ce7..803ecd24b551b 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index db096eae96163..2554c3f481917 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index a5d24b04c8c98..27d5a83e89bd6 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index c29c6c3475de8..bd0ed426dd0c1 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index ca3131d9680d8..8b9db1d51925b 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index b2fdf8c433c0a..07fa8f8f4eb62 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index c679b54afab06..30eb4b6ab447b 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index b96ec534ee587..691eec8bbca0a 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 45a4285935445..031bf9c813dae 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index 1987367d4c075..164655c32e2b6 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index 6c6582a1a1ac7..043b7b8b09f1e 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 4b2ab6c67bed3..976073d213970 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index 3a97913a75248..9ce15f163884d 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 28917bd8b1687..f9e3dd0fe8de6 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index 1ed5a7a401c33..94fb1bdf52115 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index ba40264eacefb..9dd0c9346a59c 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index 4678669348912..b39044c98c3a7 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 37c2b7486b29b..45c1b0db7bc28 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index 5aa0490e08af4..be85be3196dae 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 9a661a3e7a825..ec9a3430517d8 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 2a732d39686f9..8fc0b69f4e28e 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index a22cb9df0dd4e..5b075501e2588 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index dab06a19024a9..36b1e169cfa0f 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index f253489651f5f..92057cff0d689 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 7aee43fa71ef9..0f2aa9ddf107c 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 5069166bae6c4..b26062d911f90 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 9c93503f379fb..d5e16036d1832 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index e42bbc556432a..c9d9f5a7dc47a 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index aac3ea2826fdf..ba4012f9e1b5b 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 4ee1eabc1e149..0120e09dda4ce 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index 2b3147769fbf6..7ebe337c6b8bd 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 0d9480ff7a537..26bb228e9927d 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index 68e58936126ca..693476127fbfb 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 46339f181b32b..27f403baec1f3 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 30fcbd83bf46f..bac9aa54d4b24 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index 24053a399f316..a31537a571fb2 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index 727913760abc1..ecf2953f4f04d 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 154dc201ed8e0..8ae2f16af5826 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index e4e6cd94347a2..d1b80948307e4 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 7e62a0f0351bf..5c0e2fd063232 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 72e73c442d08a..1cb080085fccc 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 88d8cd821c0ab..d2025835c5831 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index ed1b03b2deb40..b0a7979e93218 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 34cf65ecf678f..5da02bdcb2ffc 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index aeeb5bae5f763..70844f98340c4 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 106a0a4e337e4..c40605c832b27 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 147b217d632bd..efdb8900c0efe 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index ad83c2912161f..1b29d689faab9 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 5597c0bc5b1ba..5da0c253aba57 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index c962fb9f8c51d..215d78a294f86 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index 674331b7ca6e0..2f9a87bc1df4f 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index 7aa738a92f17a..648cdd93b856c 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index 74b99e897893e..431c1c8ebf6d6 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index c75ac3d6715cf..7cbce11e04844 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 26 | 6 | 26 | 1 | +| 26 | 6 | 26 | 2 | ## Common diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index dad8c69b673ed..f9a388d3bed9b 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.devdocs.json b/api_docs/kbn_core_http_server.devdocs.json index bf3e2296978e5..e2bbe5507cc44 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -7241,10 +7241,6 @@ "plugin": "snapshotRestore", "path": "x-pack/plugins/snapshot_restore/server/routes/api/policy.ts" }, - { - "plugin": "stackConnectors", - "path": "x-pack/plugins/stack_connectors/server/routes/get_slack_api_channels.ts" - }, { "plugin": "synthetics", "path": "x-pack/plugins/synthetics/server/server.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 49b1b967e896f..24669ef76fef7 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.devdocs.json b/api_docs/kbn_core_http_server_internal.devdocs.json index 7978ebec5add0..80c7e6211eac8 100644 --- a/api_docs/kbn_core_http_server_internal.devdocs.json +++ b/api_docs/kbn_core_http_server_internal.devdocs.json @@ -519,7 +519,9 @@ "label": "versioned", "description": [], "signature": [ - "{ versionResolution: \"newest\" | \"oldest\"; strictClientVersionCheck: boolean; }" + "{ versionResolution: ", + "HandlerResolutionStrategy", + "; strictClientVersionCheck: boolean; }" ], "path": "packages/core/http/core-http-server-internal/src/http_config.ts", "deprecated": false, @@ -907,7 +909,7 @@ "label": "HttpConfigType", "description": [], "signature": [ - "{ readonly uuid?: string | undefined; readonly basePath?: string | undefined; readonly publicBaseUrl?: string | undefined; readonly name: string; readonly ssl: Readonly<{ key?: string | undefined; certificateAuthorities?: string | string[] | undefined; certificate?: string | undefined; keyPassphrase?: string | undefined; redirectHttpFromPort?: number | undefined; } & { enabled: boolean; keystore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; cipherSuites: string[]; supportedProtocols: string[]; clientAuthentication: \"none\" | \"optional\" | \"required\"; }>; readonly host: string; readonly compression: Readonly<{ referrerWhitelist?: string[] | undefined; } & { enabled: boolean; brotli: Readonly<{} & { enabled: boolean; quality: number; }>; }>; readonly port: number; readonly cors: Readonly<{} & { enabled: boolean; allowCredentials: boolean; allowOrigin: string[] | \"*\"[]; }>; readonly versioned: Readonly<{} & { versionResolution: \"newest\" | \"oldest\"; strictClientVersionCheck: boolean; }>; readonly autoListen: boolean; readonly shutdownTimeout: moment.Duration; readonly securityResponseHeaders: Readonly<{} & { referrerPolicy: \"origin\" | \"no-referrer\" | \"no-referrer-when-downgrade\" | \"origin-when-cross-origin\" | \"same-origin\" | \"strict-origin\" | \"strict-origin-when-cross-origin\" | \"unsafe-url\" | null; strictTransportSecurity: string | null; xContentTypeOptions: \"nosniff\" | null; permissionsPolicy: string | null; disableEmbedding: boolean; crossOriginOpenerPolicy: \"same-origin\" | \"unsafe-none\" | \"same-origin-allow-popups\" | null; }>; readonly customResponseHeaders: Record; readonly maxPayload: ", + "{ readonly uuid?: string | undefined; readonly basePath?: string | undefined; readonly publicBaseUrl?: string | undefined; readonly name: string; readonly ssl: Readonly<{ key?: string | undefined; certificateAuthorities?: string | string[] | undefined; certificate?: string | undefined; keyPassphrase?: string | undefined; redirectHttpFromPort?: number | undefined; } & { enabled: boolean; keystore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; cipherSuites: string[]; supportedProtocols: string[]; clientAuthentication: \"none\" | \"optional\" | \"required\"; }>; readonly host: string; readonly compression: Readonly<{ referrerWhitelist?: string[] | undefined; } & { enabled: boolean; brotli: Readonly<{} & { enabled: boolean; quality: number; }>; }>; readonly port: number; readonly cors: Readonly<{} & { enabled: boolean; allowCredentials: boolean; allowOrigin: string[] | \"*\"[]; }>; readonly versioned: Readonly<{} & { versionResolution: \"none\" | \"newest\" | \"oldest\"; strictClientVersionCheck: boolean; }>; readonly autoListen: boolean; readonly shutdownTimeout: moment.Duration; readonly securityResponseHeaders: Readonly<{} & { referrerPolicy: \"origin\" | \"no-referrer\" | \"no-referrer-when-downgrade\" | \"origin-when-cross-origin\" | \"same-origin\" | \"strict-origin\" | \"strict-origin-when-cross-origin\" | \"unsafe-url\" | null; strictTransportSecurity: string | null; xContentTypeOptions: \"nosniff\" | null; permissionsPolicy: string | null; disableEmbedding: boolean; crossOriginOpenerPolicy: \"same-origin\" | \"unsafe-none\" | \"same-origin-allow-popups\" | null; }>; readonly customResponseHeaders: Record; readonly maxPayload: ", { "pluginId": "@kbn/config-schema", "scope": "common", diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 760f1f4e6c57b..23a09858462f5 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.devdocs.json b/api_docs/kbn_core_http_server_mocks.devdocs.json index 3c0c4edef0ffa..40836ac247b24 100644 --- a/api_docs/kbn_core_http_server_mocks.devdocs.json +++ b/api_docs/kbn_core_http_server_mocks.devdocs.json @@ -27,7 +27,7 @@ "label": "createConfigService", "description": [], "signature": [ - "({ server, externalUrl, csp, }?: Partial<{ server: Partial; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; cipherSuites: string[]; supportedProtocols: string[]; clientAuthentication: \"none\" | \"optional\" | \"required\"; }>; host: string; compression: Readonly<{ referrerWhitelist?: string[] | undefined; } & { enabled: boolean; brotli: Readonly<{} & { enabled: boolean; quality: number; }>; }>; port: number; cors: Readonly<{} & { enabled: boolean; allowCredentials: boolean; allowOrigin: string[] | \"*\"[]; }>; versioned: Readonly<{} & { versionResolution: \"newest\" | \"oldest\"; strictClientVersionCheck: boolean; }>; autoListen: boolean; shutdownTimeout: moment.Duration; securityResponseHeaders: Readonly<{} & { referrerPolicy: \"origin\" | \"no-referrer\" | \"no-referrer-when-downgrade\" | \"origin-when-cross-origin\" | \"same-origin\" | \"strict-origin\" | \"strict-origin-when-cross-origin\" | \"unsafe-url\" | null; strictTransportSecurity: string | null; xContentTypeOptions: \"nosniff\" | null; permissionsPolicy: string | null; disableEmbedding: boolean; crossOriginOpenerPolicy: \"same-origin\" | \"unsafe-none\" | \"same-origin-allow-popups\" | null; }>; customResponseHeaders: Record; maxPayload: ", + "({ server, externalUrl, csp, }?: Partial<{ server: Partial; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; cipherSuites: string[]; supportedProtocols: string[]; clientAuthentication: \"none\" | \"optional\" | \"required\"; }>; host: string; compression: Readonly<{ referrerWhitelist?: string[] | undefined; } & { enabled: boolean; brotli: Readonly<{} & { enabled: boolean; quality: number; }>; }>; port: number; cors: Readonly<{} & { enabled: boolean; allowCredentials: boolean; allowOrigin: string[] | \"*\"[]; }>; versioned: Readonly<{} & { versionResolution: \"none\" | \"newest\" | \"oldest\"; strictClientVersionCheck: boolean; }>; autoListen: boolean; shutdownTimeout: moment.Duration; securityResponseHeaders: Readonly<{} & { referrerPolicy: \"origin\" | \"no-referrer\" | \"no-referrer-when-downgrade\" | \"origin-when-cross-origin\" | \"same-origin\" | \"strict-origin\" | \"strict-origin-when-cross-origin\" | \"unsafe-url\" | null; strictTransportSecurity: string | null; xContentTypeOptions: \"nosniff\" | null; permissionsPolicy: string | null; disableEmbedding: boolean; crossOriginOpenerPolicy: \"same-origin\" | \"unsafe-none\" | \"same-origin-allow-popups\" | null; }>; customResponseHeaders: Record; maxPayload: ", { "pluginId": "@kbn/config-schema", "scope": "common", @@ -64,7 +64,7 @@ "label": "{\n server,\n externalUrl,\n csp,\n}", "description": [], "signature": [ - "Partial<{ server: Partial; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; cipherSuites: string[]; supportedProtocols: string[]; clientAuthentication: \"none\" | \"optional\" | \"required\"; }>; host: string; compression: Readonly<{ referrerWhitelist?: string[] | undefined; } & { enabled: boolean; brotli: Readonly<{} & { enabled: boolean; quality: number; }>; }>; port: number; cors: Readonly<{} & { enabled: boolean; allowCredentials: boolean; allowOrigin: string[] | \"*\"[]; }>; versioned: Readonly<{} & { versionResolution: \"newest\" | \"oldest\"; strictClientVersionCheck: boolean; }>; autoListen: boolean; shutdownTimeout: moment.Duration; securityResponseHeaders: Readonly<{} & { referrerPolicy: \"origin\" | \"no-referrer\" | \"no-referrer-when-downgrade\" | \"origin-when-cross-origin\" | \"same-origin\" | \"strict-origin\" | \"strict-origin-when-cross-origin\" | \"unsafe-url\" | null; strictTransportSecurity: string | null; xContentTypeOptions: \"nosniff\" | null; permissionsPolicy: string | null; disableEmbedding: boolean; crossOriginOpenerPolicy: \"same-origin\" | \"unsafe-none\" | \"same-origin-allow-popups\" | null; }>; customResponseHeaders: Record; maxPayload: ", + "Partial<{ server: Partial; truststore: Readonly<{ path?: string | undefined; password?: string | undefined; } & {}>; cipherSuites: string[]; supportedProtocols: string[]; clientAuthentication: \"none\" | \"optional\" | \"required\"; }>; host: string; compression: Readonly<{ referrerWhitelist?: string[] | undefined; } & { enabled: boolean; brotli: Readonly<{} & { enabled: boolean; quality: number; }>; }>; port: number; cors: Readonly<{} & { enabled: boolean; allowCredentials: boolean; allowOrigin: string[] | \"*\"[]; }>; versioned: Readonly<{} & { versionResolution: \"none\" | \"newest\" | \"oldest\"; strictClientVersionCheck: boolean; }>; autoListen: boolean; shutdownTimeout: moment.Duration; securityResponseHeaders: Readonly<{} & { referrerPolicy: \"origin\" | \"no-referrer\" | \"no-referrer-when-downgrade\" | \"origin-when-cross-origin\" | \"same-origin\" | \"strict-origin\" | \"strict-origin-when-cross-origin\" | \"unsafe-url\" | null; strictTransportSecurity: string | null; xContentTypeOptions: \"nosniff\" | null; permissionsPolicy: string | null; disableEmbedding: boolean; crossOriginOpenerPolicy: \"same-origin\" | \"unsafe-none\" | \"same-origin-allow-popups\" | null; }>; customResponseHeaders: Record; maxPayload: ", { "pluginId": "@kbn/config-schema", "scope": "common", diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 0d3536a203705..402aa93e9b2c5 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 4a678fbe0658b..d2f1ffca13139 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 15aa6454aa6c7..5ae37e56f21b7 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index ac73c52a6ce76..17877019697e2 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 27ba11125fc96..e83cc31b28190 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index b66114d482452..fef7b98ad4ae5 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 4550fd26f03a0..22a22a33170c8 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index 510fa530cb9da..5a8e77da56fa5 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index fc31cfaa5f14f..1177a824e92ee 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.devdocs.json b/api_docs/kbn_core_lifecycle_browser.devdocs.json index 947feb97012fe..6c0164d6acd02 100644 --- a/api_docs/kbn_core_lifecycle_browser.devdocs.json +++ b/api_docs/kbn_core_lifecycle_browser.devdocs.json @@ -561,18 +561,10 @@ "plugin": "@kbn/core-root-browser-internal", "path": "packages/core/root/core-root-browser-internal/src/core_system.ts" }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/public/plugin.ts" - }, { "plugin": "home", "path": "src/plugins/home/public/plugin.ts" }, - { - "plugin": "data", - "path": "src/plugins/data/public/search/expressions/kibana_context.ts" - }, { "plugin": "savedObjects", "path": "src/plugins/saved_objects/public/plugin.ts" @@ -593,26 +585,6 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/dashboard_actions/index.ts" }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/datasources/form_based/form_based.tsx" - }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/datasources/form_based/form_based.tsx" - }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/visualizations/xy/visualization.tsx" - }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/visualizations/xy/visualization.tsx" - }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/visualizations/xy/visualization.tsx" - }, { "plugin": "fileUpload", "path": "x-pack/plugins/file_upload/public/kibana_services.ts" diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index 3a86f0895c0e5..b5702c33ec5cb 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 3adf9189d40eb..d78ce87a2d630 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index 8be32bf9993c8..96342a2d71aaa 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index c0a535dd226e7..62779de54d792 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index 1d192c66d458f..9e4d1bca827fd 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 741bdf6854a05..eddf2a13143df 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 849f1fb7642cc..6787935eb8584 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 3f2479a0ebb0f..99be57fa5ae14 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index 9d0d95f5193a5..a84adc015efdb 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index ffc4b5b1ec9cb..969abe2ba843e 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index ed151f736efce..178372659de9f 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 2a0b5282f1ad1..cd07cbeb503f5 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index 43394ca0c57a4..cc4417259162a 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index 142833d70c156..f56eb8b931c24 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index 6301ac835565e..c85ad3d88efa4 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index ded156f2815b6..72d00b36c7605 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index d9c895c98efdb..e793f3309ae71 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 137479a013d19..51250a42629cd 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index 174432c4869af..d748e6c111653 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 7ae4e9a195660..3e7be9fdac160 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index 0991f6a4cdbd6..fcb2c1ad441fc 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index 91ee4c8ee8322..f1ae03938e1e0 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 5698c542fb01e..cd53753661d92 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index 952d6c99e599c..326bc9b696620 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 0f1a00fda05f3..b8992d708726f 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 1df0ce209e97c..7b2a7418caf84 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index f6e841d51a5d0..ff8a92cfc953b 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index 8629f2d3c0db8..04a54990deb0f 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 7e022fafc8272..224884d3806a0 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 339b0d50603a8..5feae586499d8 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index 113a993067b64..b0a1ae726fd77 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index b51f85589d1c3..c501425c79f14 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index bd7d6de3baabf..d8c19431838f1 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index eea2087d0183f..2893edfec3f32 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.devdocs.json b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json index 1e72ef2cfb083..7af458553d3a3 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json @@ -910,14 +910,6 @@ "plugin": "dataViews", "path": "src/plugins/data_views/common/lib/get_title.ts" }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts" - }, { "plugin": "home", "path": "src/plugins/home/public/application/kibana_services.ts" @@ -1996,10 +1988,6 @@ "plugin": "@kbn/core-saved-objects-browser-mocks", "path": "packages/core/saved-objects/core-saved-objects-browser-mocks/src/saved_objects_service.mock.ts" }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.ts" - }, { "plugin": "discover", "path": "src/plugins/discover/public/application/main/services/discover_state.test.ts" diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 66ffecb61ad78..fd9067a8e6158 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.devdocs.json b/api_docs/kbn_core_saved_objects_api_server.devdocs.json index fc0d4c83fdcab..2d11fb4b9bb95 100644 --- a/api_docs/kbn_core_saved_objects_api_server.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_server.devdocs.json @@ -2670,18 +2670,6 @@ "plugin": "actions", "path": "x-pack/plugins/actions/server/types.ts" }, - { - "plugin": "actions", - "path": "x-pack/plugins/actions/server/types.ts" - }, - { - "plugin": "actions", - "path": "x-pack/plugins/actions/server/types.ts" - }, - { - "plugin": "actions", - "path": "x-pack/plugins/actions/server/types.ts" - }, { "plugin": "alerting", "path": "x-pack/plugins/alerting/common/rule.ts" diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index b2c169d117dd8..e2ca55bc4e9e8 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index eb944a795ed77..7e57cd32304ed 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index c84fb04e06eaf..926bd86c02dbf 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 88717a398ddd5..98d0ac6e86376 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index 5bf8d0583ab3b..bab69b2c56342 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index d3ef4e41e9da3..7e6742810e67a 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.devdocs.json b/api_docs/kbn_core_saved_objects_browser_mocks.devdocs.json index 8d5d226883f46..ebe7a8f233c79 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.devdocs.json +++ b/api_docs/kbn_core_saved_objects_browser_mocks.devdocs.json @@ -48,14 +48,6 @@ "plugin": "@kbn/core", "path": "src/core/public/mocks.ts" }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.test.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/public/saved_objects_client_wrapper.test.ts" - }, { "plugin": "@kbn/core-plugins-browser-internal", "path": "packages/core/plugins/core-plugins-browser-internal/src/plugins_service.test.ts" diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 1d84412aef0bd..991f6be78d252 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.devdocs.json b/api_docs/kbn_core_saved_objects_common.devdocs.json index b48b6f5a2eb1f..cd61e4bd76984 100644 --- a/api_docs/kbn_core_saved_objects_common.devdocs.json +++ b/api_docs/kbn_core_saved_objects_common.devdocs.json @@ -2342,14 +2342,6 @@ "plugin": "dataViews", "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts" }, - { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/common/search/expressions/kibana_context.ts" - }, { "plugin": "data", "path": "src/plugins/data/common/search/search_source/extract_references.ts" diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 63a2ba8234e9d..f53ae5edb4826 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index dfca597c8941d..258aa0c529bbb 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index 6ac4e3550bc03..973ba8d4b52bb 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index d16f562db9b2f..6fe2b0f2e8056 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index 9f818e3a48b50..e0f57ed175730 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.devdocs.json b/api_docs/kbn_core_saved_objects_server.devdocs.json index dc7c19230b2dc..5354c336cd82f 100644 --- a/api_docs/kbn_core_saved_objects_server.devdocs.json +++ b/api_docs/kbn_core_saved_objects_server.devdocs.json @@ -6135,18 +6135,6 @@ "plugin": "actions", "path": "x-pack/plugins/actions/server/types.ts" }, - { - "plugin": "actions", - "path": "x-pack/plugins/actions/server/types.ts" - }, - { - "plugin": "actions", - "path": "x-pack/plugins/actions/server/types.ts" - }, - { - "plugin": "actions", - "path": "x-pack/plugins/actions/server/types.ts" - }, { "plugin": "alerting", "path": "x-pack/plugins/alerting/common/rule.ts" diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 28e28ae0fb8f8..b3690a047be7e 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 2303dc1653032..66640e5420539 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 5291300831b12..d1822d583e682 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index ad7b23d9808b0..0e68dc683e23f 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 3130c81309183..ef8864b10629e 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 01bf5f1fee4b4..d9f01d08ba38e 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index 1f0c98bd16e58..bbb3a83f5c960 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index 720a2eeae6a53..d4ee4d97d6369 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index 45937b8eefe07..25d9f5ad30d6d 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index f680f9e7a6fc8..9227e74ee3c33 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index f7d7e6690aca0..e35964915ee67 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index dbf83204bdd9c..0d42a174b8907 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 5f211af40dd21..d861dd91eaa01 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index dc5cf5f06d4f0..0e7b965fd0cc9 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index a0619184e4f67..f21c6cf50b3a4 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 8675d3735df54..0c99b9a118cc1 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 089fa642974bd..6d248ab515df9 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 601783351cbbe..57c64fff3b87a 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 06a0983edd554..071698435008d 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 040c22e46f86f..8cff18c922317 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index bf42a8e5961ab..136900eac8199 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 47e2dc5550d0f..168fe47ca307e 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index 461229f5e1692..578f04c2c5e34 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index 30386877ed1af..c3fdc4fd9dda3 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index 802fce02b4b33..acffe2a0f19f6 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index dbbcd33c966e4..58b2c0cc99911 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index 6d254276b596f..7ca96d1e141be 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index e9c1def1191ed..51beded6653cf 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index 215cd8d4a462e..4beadaf63d268 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 71870b2eae9f4..2d1bf314f08b3 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-mocks'] --- import kbnCoreUserSettingsServerMocksObj from './kbn_core_user_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 37bd8d78b6507..8ec181c0de112 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index a7f4b85747e69..2ce03d0103e57 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 80e85eb239982..7bc4bd91ba2c5 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 39ba33d7434fa..b5ee9a2e6d5f1 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index caf091d68cc52..d4f49580e0d1b 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_analytics.mdx b/api_docs/kbn_deeplinks_analytics.mdx index b8a35d19c437f..cb5a24f2fae69 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-analytics'] --- import kbnDeeplinksAnalyticsObj from './kbn_deeplinks_analytics.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_devtools.mdx b/api_docs/kbn_deeplinks_devtools.mdx index c64db36a1b1b1..4a855e2d32a26 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index ad04b8627b959..0dde10bf0bfbc 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_management.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index be98fe964e44d..0bf5b3649cef4 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index d77fbfbb49925..dad07297d9f48 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index a00ac965111a8..cccc0ab00111c 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index c8d7e9a8b8f3d..87c65f1115b60 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-analytics'] --- import kbnDefaultNavAnalyticsObj from './kbn_default_nav_analytics.devdocs.json'; diff --git a/api_docs/kbn_default_nav_devtools.mdx b/api_docs/kbn_default_nav_devtools.mdx index 505927edd06ff..c03336b1150ee 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-devtools'] --- import kbnDefaultNavDevtoolsObj from './kbn_default_nav_devtools.devdocs.json'; diff --git a/api_docs/kbn_default_nav_management.mdx b/api_docs/kbn_default_nav_management.mdx index 2aa776efa6900..1d2937812cedb 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-management'] --- import kbnDefaultNavManagementObj from './kbn_default_nav_management.devdocs.json'; diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index 883ef70555212..d5b56ac76b984 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-ml'] --- import kbnDefaultNavMlObj from './kbn_default_nav_ml.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 1b2472354d2b6..2a712353f6780 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index f1050872288b0..4cfd7903f48fc 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index c2f41bd2233d4..d310a7ffc618b 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 3a5c306c24ea3..57e0d6c31600a 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 5864ee421716c..ca03416fafdcc 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 3204d5104f129..0366678c15ecb 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_dom_drag_drop.devdocs.json b/api_docs/kbn_dom_drag_drop.devdocs.json index e799faf895dc9..cb21105a32b80 100644 --- a/api_docs/kbn_dom_drag_drop.devdocs.json +++ b/api_docs/kbn_dom_drag_drop.devdocs.json @@ -29,7 +29,7 @@ "\nA React drag / drop provider that derives its state from a RootDragDropProvider. If\npart of a React application is rendered separately from the root, this provider can\nbe used to enable drag / drop functionality within the disconnected part.\n" ], "signature": [ - "({\n dragging,\n setDragging,\n setKeyboardMode,\n keyboardMode,\n activeDropTarget,\n setActiveDropTarget,\n setA11yMessage,\n registerDropTarget,\n dropTargetsByOrder,\n dataTestSubjPrefix,\n onTrackUICounterEvent,\n children,\n}: ", + "({ value, children }: ", "ProviderProps", ") => JSX.Element" ], @@ -42,7 +42,7 @@ "id": "def-common.ChildDragDropProvider.$1", "type": "Object", "tags": [], - "label": "{\n dragging,\n setDragging,\n setKeyboardMode,\n keyboardMode,\n activeDropTarget,\n setActiveDropTarget,\n setA11yMessage,\n registerDropTarget,\n dropTargetsByOrder,\n dataTestSubjPrefix,\n onTrackUICounterEvent,\n children,\n}", + "label": "{ value, children }", "description": [], "signature": [ "ProviderProps" @@ -150,15 +150,11 @@ "parentPluginId": "@kbn/dom-drag-drop", "id": "def-common.ReorderProvider", "type": "Function", - "tags": [ - "constructor" - ], + "tags": [], "label": "ReorderProvider", - "description": [ - "\nTo create a reordering group, surround the elements from the same group with a `ReorderProvider`" - ], + "description": [], "signature": [ - "({\n id,\n children,\n className,\n draggingHeight = REORDER_ITEM_HEIGHT,\n dataTestSubj = DEFAULT_DATA_TEST_SUBJ,\n}: { id: string; children: React.ReactNode; className?: string | undefined; draggingHeight?: number | undefined; dataTestSubj?: string | undefined; }) => JSX.Element" + "({\n children,\n className,\n dataTestSubj = DEFAULT_DATA_TEST_SUBJ,\n}: { children: React.ReactNode; className?: string | undefined; dataTestSubj?: string | undefined; }) => JSX.Element" ], "path": "packages/kbn-dom-drag-drop/src/providers/reorder_provider.tsx", "deprecated": false, @@ -169,23 +165,12 @@ "id": "def-common.ReorderProvider.$1", "type": "Object", "tags": [], - "label": "{\n id,\n children,\n className,\n draggingHeight = REORDER_ITEM_HEIGHT,\n dataTestSubj = DEFAULT_DATA_TEST_SUBJ,\n}", + "label": "{\n children,\n className,\n dataTestSubj = DEFAULT_DATA_TEST_SUBJ,\n}", "description": [], "path": "packages/kbn-dom-drag-drop/src/providers/reorder_provider.tsx", "deprecated": false, "trackAdoption": false, "children": [ - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.ReorderProvider.$1.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "path": "packages/kbn-dom-drag-drop/src/providers/reorder_provider.tsx", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "@kbn/dom-drag-drop", "id": "def-common.ReorderProvider.$1.children", @@ -214,20 +199,6 @@ "deprecated": false, "trackAdoption": false }, - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.ReorderProvider.$1.draggingHeight", - "type": "number", - "tags": [], - "label": "draggingHeight", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/reorder_provider.tsx", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "@kbn/dom-drag-drop", "id": "def-common.ReorderProvider.$1.dataTestSubj", @@ -254,11 +225,11 @@ "type": "Function", "tags": [], "label": "RootDragDropProvider", - "description": [ - "\nA React provider that tracks the dragging state. This should\nbe placed at the root of any React application that supports\ndrag / drop.\n" - ], + "description": [], "signature": [ - "({\n children,\n dataTestSubj = DEFAULT_DATA_TEST_SUBJ,\n onTrackUICounterEvent,\n}: { children: React.ReactNode; dataTestSubj?: string | undefined; onTrackUICounterEvent?: ((event: string) => void) | undefined; }) => JSX.Element" + "({\n children,\n dataTestSubj = DEFAULT_DATA_TEST_SUBJ,\n customMiddleware,\n}: { children: React.ReactNode; dataTestSubj?: string | undefined; customMiddleware?: ", + "CustomMiddleware", + " | undefined; }) => JSX.Element" ], "path": "packages/kbn-dom-drag-drop/src/providers/providers.tsx", "deprecated": false, @@ -269,7 +240,7 @@ "id": "def-common.RootDragDropProvider.$1", "type": "Object", "tags": [], - "label": "{\n children,\n dataTestSubj = DEFAULT_DATA_TEST_SUBJ,\n onTrackUICounterEvent,\n}", + "label": "{\n children,\n dataTestSubj = DEFAULT_DATA_TEST_SUBJ,\n customMiddleware,\n}", "description": [], "path": "packages/kbn-dom-drag-drop/src/providers/providers.tsx", "deprecated": false, @@ -305,13 +276,14 @@ }, { "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.RootDragDropProvider.$1.onTrackUICounterEvent", + "id": "def-common.RootDragDropProvider.$1.customMiddleware", "type": "Function", "tags": [], - "label": "onTrackUICounterEvent", + "label": "customMiddleware", "description": [], "signature": [ - "((event: string) => void) | undefined" + "CustomMiddleware", + " | undefined" ], "path": "packages/kbn-dom-drag-drop/src/providers/providers.tsx", "deprecated": false, @@ -322,6 +294,30 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dom-drag-drop", + "id": "def-common.useDragDropContext", + "type": "Function", + "tags": [], + "label": "useDragDropContext", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "@kbn/dom-drag-drop", + "scope": "common", + "docId": "kibKbnDomDragDropPluginApi", + "section": "def-common.DragContextValue", + "text": "DragContextValue" + } + ], + "path": "packages/kbn-dom-drag-drop/src/providers/providers.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [ @@ -331,9 +327,7 @@ "type": "Interface", "tags": [], "label": "DragContextState", - "description": [ - "\nThe shape of the drag / drop context." - ], + "description": [], "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", "deprecated": false, "trackAdoption": false, @@ -374,96 +368,15 @@ "deprecated": false, "trackAdoption": false }, - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.setKeyboardMode", - "type": "Function", - "tags": [], - "label": "setKeyboardMode", - "description": [ - "\nkeyboard mode" - ], - "signature": [ - "(mode: boolean) => void" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.setKeyboardMode.$1", - "type": "boolean", - "tags": [], - "label": "mode", - "description": [], - "signature": [ - "boolean" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.setDragging", - "type": "Function", - "tags": [], - "label": "setDragging", - "description": [ - "\nSet the item being dragged." - ], - "signature": [ - "(dragging?: ", - { - "pluginId": "@kbn/dom-drag-drop", - "scope": "common", - "docId": "kibKbnDomDragDropPluginApi", - "section": "def-common.DraggingIdentifier", - "text": "DraggingIdentifier" - }, - " | undefined) => void" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.setDragging.$1", - "type": "CompoundType", - "tags": [], - "label": "dragging", - "description": [], - "signature": [ - { - "pluginId": "@kbn/dom-drag-drop", - "scope": "common", - "docId": "kibKbnDomDragDropPluginApi", - "section": "def-common.DraggingIdentifier", - "text": "DraggingIdentifier" - }, - " | undefined" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - } - ], - "returnComment": [] - }, { "parentPluginId": "@kbn/dom-drag-drop", "id": "def-common.DragContextState.activeDropTarget", "type": "CompoundType", "tags": [], "label": "activeDropTarget", - "description": [], + "description": [ + "\ncurrently selected drop target" + ], "signature": [ "DropIdentifier", " | undefined" @@ -478,7 +391,9 @@ "type": "Object", "tags": [], "label": "dropTargetsByOrder", - "description": [], + "description": [ + "\ncurrently registered drop targets" + ], "signature": [ "Record void" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.setActiveDropTarget.$1", - "type": "CompoundType", - "tags": [], - "label": "newTarget", - "description": [], - "signature": [ - "DropIdentifier", - " | undefined" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.setA11yMessage", - "type": "Function", - "tags": [], - "label": "setA11yMessage", - "description": [], - "signature": [ - "(message: string) => void" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.setA11yMessage.$1", - "type": "string", - "tags": [], - "label": "message", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.registerDropTarget", - "type": "Function", - "tags": [], - "label": "registerDropTarget", - "description": [], - "signature": [ - "(order: number[], dropTarget?: ", - "DropIdentifier", - " | undefined) => void" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.registerDropTarget.$1", - "type": "Array", - "tags": [], - "label": "order", - "description": [], - "signature": [ - "number[]" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.registerDropTarget.$2", - "type": "CompoundType", - "tags": [], - "label": "dropTarget", - "description": [], - "signature": [ - "DropIdentifier", - " | undefined" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": false - } - ], - "returnComment": [] - }, { "parentPluginId": "@kbn/dom-drag-drop", "id": "def-common.DragContextState.dataTestSubjPrefix", @@ -617,40 +415,6 @@ "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", "deprecated": false, "trackAdoption": false - }, - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.onTrackUICounterEvent", - "type": "Function", - "tags": [], - "label": "onTrackUICounterEvent", - "description": [ - "\nA custom callback for telemetry" - ], - "signature": [ - "((event: string) => void) | undefined" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContextState.onTrackUICounterEvent.$1", - "type": "string", - "tags": [], - "label": "event", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] } ], "initialIsOpen": false @@ -713,6 +477,54 @@ ], "enums": [], "misc": [ + { + "parentPluginId": "@kbn/dom-drag-drop", + "id": "def-common.DragContextValue", + "type": "Type", + "tags": [], + "label": "DragContextValue", + "description": [], + "signature": [ + "[state: ", + { + "pluginId": "@kbn/dom-drag-drop", + "scope": "common", + "docId": "kibKbnDomDragDropPluginApi", + "section": "def-common.DragContextState", + "text": "DragContextState" + }, + ", dispatch: React.Dispatch<", + { + "pluginId": "@kbn/dom-drag-drop", + "scope": "common", + "docId": "kibKbnDomDragDropPluginApi", + "section": "def-common.DragDropAction", + "text": "DragDropAction" + }, + ">, customMiddleware?: ", + "CustomMiddleware", + " | undefined]" + ], + "path": "packages/kbn-dom-drag-drop/src/providers/types.tsx", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/dom-drag-drop", + "id": "def-common.DragDropAction", + "type": "Type", + "tags": [], + "label": "DragDropAction", + "description": [], + "signature": [ + "ResetStateAction | RegisterDropTargetAction | LeaveDropTargetAction | SelectDropTargetAction | DragToTargetAction | StartDraggingAction | EndDraggingAction" + ], + "path": "packages/kbn-dom-drag-drop/src/providers/providers.tsx", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/dom-drag-drop", "id": "def-common.DragDropIdentifier", @@ -772,31 +584,6 @@ } ], "objects": [ - { - "parentPluginId": "@kbn/dom-drag-drop", - "id": "def-common.DragContext", - "type": "Object", - "tags": [], - "label": "DragContext", - "description": [ - "\nThe drag / drop context singleton, used like so:\n\nconst { dragging, setDragging } = useContext(DragContext);" - ], - "signature": [ - "React.Context<", - { - "pluginId": "@kbn/dom-drag-drop", - "scope": "common", - "docId": "kibKbnDomDragDropPluginApi", - "section": "def-common.DragContextState", - "text": "DragContextState" - }, - ">" - ], - "path": "packages/kbn-dom-drag-drop/src/providers/providers.tsx", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "@kbn/dom-drag-drop", "id": "def-common.DropTargetSwapDuplicateCombine", diff --git a/api_docs/kbn_dom_drag_drop.mdx b/api_docs/kbn_dom_drag_drop.mdx index 0d527539547d0..58928b38b8d0c 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dom-drag-drop'] --- import kbnDomDragDropObj from './kbn_dom_drag_drop.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 52 | 0 | 34 | 4 | +| 39 | 0 | 26 | 5 | ## Common diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 33de3e7927999..39725a714fac7 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 0a7e33ee62fbd..bee49db0feafb 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 01b9489f715b7..5a7a6a6549157 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.devdocs.json b/api_docs/kbn_elastic_assistant.devdocs.json index eafb72239144e..393e7ea5d5bda 100644 --- a/api_docs/kbn_elastic_assistant.devdocs.json +++ b/api_docs/kbn_elastic_assistant.devdocs.json @@ -122,7 +122,7 @@ "label": "AssistantProvider", "description": [], "signature": [ - "({ actionTypeRegistry, augmentMessageCodeBlocks, baseAllow, baseAllowReplacement, defaultAllow, defaultAllowReplacement, basePromptContexts, baseQuickPrompts, baseSystemPrompts, children, getComments, http, getInitialConversations, nameSpace, setConversations, setDefaultAllow, setDefaultAllowReplacement, title, }: React.PropsWithChildren) => JSX.Element" + "({ actionTypeRegistry, augmentMessageCodeBlocks, baseAllow, baseAllowReplacement, defaultAllow, defaultAllowReplacement, docLinks, basePromptContexts, baseQuickPrompts, baseSystemPrompts, children, getComments, http, getInitialConversations, nameSpace, setConversations, setDefaultAllow, setDefaultAllowReplacement, title, }: React.PropsWithChildren) => JSX.Element" ], "path": "x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx", "deprecated": false, @@ -133,7 +133,7 @@ "id": "def-public.AssistantProvider.$1", "type": "CompoundType", "tags": [], - "label": "{\n actionTypeRegistry,\n augmentMessageCodeBlocks,\n baseAllow,\n baseAllowReplacement,\n defaultAllow,\n defaultAllowReplacement,\n basePromptContexts = [],\n baseQuickPrompts = [],\n baseSystemPrompts = BASE_SYSTEM_PROMPTS,\n children,\n getComments,\n http,\n getInitialConversations,\n nameSpace = DEFAULT_ASSISTANT_NAMESPACE,\n setConversations,\n setDefaultAllow,\n setDefaultAllowReplacement,\n title = DEFAULT_ASSISTANT_TITLE,\n}", + "label": "{\n actionTypeRegistry,\n augmentMessageCodeBlocks,\n baseAllow,\n baseAllowReplacement,\n defaultAllow,\n defaultAllowReplacement,\n docLinks,\n basePromptContexts = [],\n baseQuickPrompts = [],\n baseSystemPrompts = BASE_SYSTEM_PROMPTS,\n children,\n getComments,\n http,\n getInitialConversations,\n nameSpace = DEFAULT_ASSISTANT_NAMESPACE,\n setConversations,\n setDefaultAllow,\n setDefaultAllowReplacement,\n title = DEFAULT_ASSISTANT_TITLE,\n}", "description": [], "signature": [ "React.PropsWithChildren" @@ -406,17 +406,19 @@ }, { "parentPluginId": "@kbn/elastic-assistant", - "id": "def-public.CodeBlockDetails.controlContainer", - "type": "CompoundType", + "id": "def-public.CodeBlockDetails.getControlContainer", + "type": "Function", "tags": [], - "label": "controlContainer", + "label": "getControlContainer", "description": [], "signature": [ - "boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined" + "(() => Element | undefined) | undefined" ], "path": "x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/helpers.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "children": [], + "returnComment": [] }, { "parentPluginId": "@kbn/elastic-assistant", @@ -538,6 +540,20 @@ "path": "x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/elastic-assistant", + "id": "def-public.Conversation.excludeFromLastConversationStorage", + "type": "CompoundType", + "tags": [], + "label": "excludeFromLastConversationStorage", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index c802372b2e52d..fdbc701fd75f8 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/security-solution](https://github.com/orgs/elastic/teams/secur | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 83 | 4 | 64 | 3 | +| 84 | 4 | 65 | 3 | ## Client diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index fde2978222074..4583437116ed3 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index bea45fe5f81db..c192f40b3e6ff 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index 6cffffa0fd73d..231888b12b04b 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index a6bc121fc6aff..c0fcbe324fdf9 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index b195f3df16944..17938a13b4862 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index b323287e872db..8d7f731a5df0e 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index d039225ecc92b..c0f6860c9f179 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 70925b3845fee..e1f856d0ab9f4 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index a515554efffc5..88d87cac61f0e 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 2c38732cb636f..289566868f693 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index d0295c159e3fa..20fd1cfa45650 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index 7fca93e38c541..8e18ba2d8464e 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index 91e94927595d5..1985b1736ebcb 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index c1d73051af25c..9e82ac0fcc836 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 40370acb1784e..70cde35d17f58 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 02348fc67c091..82f91568699a3 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index f05a09895b88d..cf0a8393637c8 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index 8849b2f5ab184..72be599ece123 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 1ba7008ab6638..ee6ff9632aec1 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index 2c62343e76c3d..2662cf16f57a3 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 7e396b8ae300b..d89316dc9b5c1 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index c07fb40bbd7da..a1b3bbcf539d8 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 934417339881d..3fc5286082e73 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 3722d837a9923..e8c5e3b3a8327 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index de2d20a62f285..742da0b7bfca5 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 1a122b833d321..ba6ea78e2ca0d 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index a6ee77e409e7f..67bb54d9bf4a7 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 3b78cc43ba5d9..5d1390c382f5f 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index 58b7df089098b..00eb6d8971c0a 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 183ed01b6d16a..43de10c6224b9 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index e4c8f152d90aa..daf02df605db7 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index f929af1dbdba9..790e652c5603c 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index fc037d467484d..67c280d2eeaa9 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index d617682f96def..a344b90a2f4ae 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index 4f50aa3e491a8..398e3355b8610 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index cdde4a541e2b5..c6d4d72f7d780 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 23b99b772d185..91479d9b5f8ca 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index 4e2e69a2e797f..422243dc06de2 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 440debb42a627..39bf72758c217 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index c932b4df1b5eb..788a14d6420f5 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 782a1573f16c6..380e1b3080ba6 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index 9ff1ad7f589cb..9ce89b3b98b22 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index bd1a4d132e96b..e0a5e8371540e 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index 1857ec5455f67..2cbad02d948b8 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index bad0c07c5e2d9..4eb1bbccce1bc 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 4f69a02dd38d8..c0605225415e2 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 3df13ec3f5838..96fedeaf4c54c 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index 276610a8664b1..d2926fd658f34 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index 06f3f339e5228..e4f91889f4e9f 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index 885baa9b72f7e..9adc58f2fc685 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index 8cafe4711fc12..58ddc30ac84b9 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index 8e35803247d6a..a29a4ff22b499 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index a0a8e9cbc0e74..4bac0afd9d25f 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index 50655e98fb617..0c4f7f52b5a30 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index a569fb3a2893a..7726b79aad379 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index 4c7471399d8f0..e5fa63da7b23b 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index cb7eabd047721..1c35cd7694f6e 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 3209bbf20dc42..c5b9edf4fb589 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index bfd6f928335af..569e8ad2a5af6 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index 13074ba702078..20fd23405f1a0 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 098d75de19a56..87413522a79eb 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 418d80a0a1be6..1398073968c9f 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index fed056a43bc6f..1f3356b19495c 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index e93b496bbab5f..38e60d02da6e1 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 216fab984f5b3..c4da07bafeaf8 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index d33f6f814048f..ee0d64be02fe8 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 57ac187ec1b7f..f5c4807976eed 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 558568537ea4e..1c0a29740759b 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 09e1809419c34..61c55ba2567d5 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index a02eedcd6af1f..5eaf16e278f9d 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index ba00b414ac4b5..9d190c2833e16 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index 14ff014b7d2ca..3993e2f7e6ce7 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 8a166c9693471..e49279f6cc307 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index af54819ee472b..9e0c25df23689 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 5d347d26dd1ea..d94bee2a776f2 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 04d3a72607fb5..698465332616e 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index e0848eeaabf14..153025511ddd2 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index 3346e49a9517e..7288d7de6d8c7 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index d6a5191cfbdab..0da07793a2099 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index ed7d5ad45739c..208c004c106c5 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 6c007cecc1d88..ed28c5160fba7 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index b44cb01bfb3b1..cba5333c4b71f 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index 6d34ada646a7e..9081336b1c441 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 4de618201333a..9d7bd2e57bf85 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index d6116b938e28a..ca510f938a1b6 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 8b408c1821073..897ff8cd6b8a9 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index c52baad0c9c8b..255e093ee4a30 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 97109a761ff0e..384c946b80a7a 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 1494f1bd90fc9..48f85be23e0d8 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index aca5bc0b1dfeb..670dda82b079c 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 07870909bdeba..6322400b7dd27 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 7792cd57310ed..22e7894678625 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index c1c05cb1860ca..bfbef50ea9d21 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 285c4deaa9820..1e927b9d6395a 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 7a3c7aa77f380..54c2d9d0ef362 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 57f9d245c83b2..0a775b3472763 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index eb78f07165caa..482efde21091f 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 0eb9d2e89af20..cfc17dca605ad 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 3727238fe8e0b..4934a8e41ef9f 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 4fa84946cbf60..28ce9b060cd62 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 1bea914f22c46..c2c4ab94edafe 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 582c82ec613ee..7c6908341d061 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index c80db5f1b0857..089e76188f6eb 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index ee20dd93622c3..c312898a268b1 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 0b74172050a64..4c71118232b4e 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 1fa6147ae0275..89189f8e924a6 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index ec89326770398..87672072d3ffe 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 17f89e87fddd3..ad61125a94604 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 3a182147657cd..eae1a84873cdd 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index b6f9d77fcbf87..622e612678b17 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index 629e37212945a..510bf1b064e75 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index b4d647903bd81..9a781c01498a5 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index ba7f297713166..a0437a847aecd 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index 971462c7f20bc..9c730cc4f160d 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index a65fe163285e6..858605305b68a 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index 098fdcf94f640..54f95b7e0c24e 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index 755654739a857..6399e7d8e8a69 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index b6c93013b628e..3671a5dda1223 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index f3c12ba2329dd..743619d605cf8 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index b7f8ef79ef134..0fde065fdbfa5 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index f8215859c41df..e8d040be29770 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 263e526d1db3d..0dcdf4c911fc8 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index 93350f7657073..bce5f42f61130 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 3b4f98cab0cfd..0ac2a6ef50a00 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index bbe732d7a686f..5039e2d6851d1 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index b6b6121091dc0..78af350aa5e02 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index a8d6eab0c3f4c..1dd60257c2abf 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index dba775f0e6abf..68575c074ef16 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index 1da43db5bcb79..7eede03c67cee 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index ccd3f138d4d99..20bcc82119765 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index 2d8a1630155f2..0361078a3def4 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index ddd16877f7cf6..c37f10c4b8a43 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index 0f45858d652ec..d79cfcdb1bd15 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index 5aa8f4fbad341..8a1f2ff327d7e 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index 5d639dd48ac43..419ba60fa98ee 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 6dbc86accb125..15e85910ddade 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index 725f82c1e4819..cf214ec5ea4cf 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 5de13ff0cbb66..631bf32199376 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index 28e5c8be8a861..8afcde478e336 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index de3acba1cf40a..e198f4919edf5 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 7f3d7cc856f60..f8c5e2be4b2a0 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 2b1bf7cb027df..20ceb2ccd075c 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.devdocs.json b/api_docs/kbn_slo_schema.devdocs.json index fe5ba2d2391d8..d7a3e97fed452 100644 --- a/api_docs/kbn_slo_schema.devdocs.json +++ b/api_docs/kbn_slo_schema.devdocs.json @@ -535,7 +535,7 @@ "label": "CreateSLOInput", "description": [], "signature": [ - "{ name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; } & { id?: string | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; tags?: string[] | undefined; }" + "{ name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; } & { id?: string | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; tags?: string[] | undefined; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -550,7 +550,7 @@ "label": "CreateSLOParams", "description": [], "signature": [ - "{ name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: ", + "{ name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: ", { "pluginId": "@kbn/slo-schema", "scope": "common", @@ -695,7 +695,7 @@ "label": "FindSLOResponse", "description": [], "signature": [ - "{ page: number; perPage: number; total: number; results: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; })[]; }" + "{ page: number; perPage: number; total: number; results: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; })[]; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -725,7 +725,7 @@ "label": "GetPreviewDataParams", "description": [], "signature": [ - "{ indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; }" + "{ indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -770,7 +770,22 @@ "label": "GetSLOResponse", "description": [], "signature": [ - "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; }" + "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; }" + ], + "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/slo-schema", + "id": "def-common.HistogramIndicator", + "type": "Type", + "tags": [], + "label": "HistogramIndicator", + "description": [], + "signature": [ + "{ type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -800,7 +815,7 @@ "label": "Indicator", "description": [], "signature": [ - "{ type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }" + "{ type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -815,7 +830,7 @@ "label": "IndicatorType", "description": [], "signature": [ - "\"sli.apm.transactionDuration\" | \"sli.apm.transactionErrorRate\" | \"sli.kql.custom\" | \"sli.metric.custom\"" + "\"sli.apm.transactionDuration\" | \"sli.apm.transactionErrorRate\" | \"sli.kql.custom\" | \"sli.metric.custom\" | \"sli.histogram.custom\"" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -875,7 +890,7 @@ "label": "SLOResponse", "description": [], "signature": [ - "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }" + "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -890,7 +905,7 @@ "label": "SLOWithSummaryResponse", "description": [], "signature": [ - "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; }" + "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -1004,7 +1019,7 @@ "label": "UpdateSLOInput", "description": [], "signature": [ - "{ name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | undefined; timeWindow?: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; } | undefined; budgetingMethod?: \"occurrences\" | \"timeslices\" | undefined; objective?: ({ target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }) | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; tags?: string[] | undefined; }" + "{ name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; } | undefined; timeWindow?: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; } | undefined; budgetingMethod?: \"occurrences\" | \"timeslices\" | undefined; objective?: ({ target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }) | undefined; settings?: { syncDelay?: string | undefined; frequency?: string | undefined; } | undefined; tags?: string[] | undefined; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -1019,7 +1034,7 @@ "label": "UpdateSLOParams", "description": [], "signature": [ - "{ name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | undefined; timeWindow?: { duration: ", + "{ name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; } | undefined; timeWindow?: { duration: ", { "pluginId": "@kbn/slo-schema", "scope": "common", @@ -1074,7 +1089,7 @@ "label": "UpdateSLOResponse", "description": [], "signature": [ - "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }" + "{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -1775,7 +1790,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -2443,7 +2530,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -2745,7 +2904,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; }>; }>" + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; }>; }>" ], "path": "x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts", "deprecated": false, @@ -3043,7 +3274,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -3168,22 +3471,124 @@ }, { "parentPluginId": "@kbn/slo-schema", - "id": "def-common.historicalSummarySchema", + "id": "def-common.histogramIndicatorSchema", "type": "Object", "tags": [], - "label": "historicalSummarySchema", + "label": "histogramIndicatorSchema", "description": [], "signature": [ - "IntersectionC", - "<[", "TypeC", - "<{ date: ", - "Type", - "; }>, ", - "TypeC", - "<{ status: ", - "UnionC", - "<[", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>" + ], + "path": "x-pack/packages/kbn-slo-schema/src/schema/indicators.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/slo-schema", + "id": "def-common.histogramIndicatorTypeSchema", + "type": "Object", + "tags": [], + "label": "histogramIndicatorTypeSchema", + "description": [], + "signature": [ + "LiteralC", + "<\"sli.histogram.custom\">" + ], + "path": "x-pack/packages/kbn-slo-schema/src/schema/indicators.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/slo-schema", + "id": "def-common.historicalSummarySchema", + "type": "Object", + "tags": [], + "label": "historicalSummarySchema", + "description": [], + "signature": [ + "IntersectionC", + "<[", + "TypeC", + "<{ date: ", + "Type", + "; }>, ", + "TypeC", + "<{ status: ", + "UnionC", + "<[", "LiteralC", "<\"NO_DATA\">, ", "LiteralC", @@ -3391,7 +3796,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>" + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>" ], "path": "x-pack/packages/kbn-slo-schema/src/schema/indicators.ts", "deprecated": false, @@ -3431,7 +3908,9 @@ "LiteralC", "<\"sli.kql.custom\">, ", "LiteralC", - "<\"sli.metric.custom\">]>" + "<\"sli.metric.custom\">, ", + "LiteralC", + "<\"sli.histogram.custom\">]>" ], "path": "x-pack/packages/kbn-slo-schema/src/schema/indicators.ts", "deprecated": false, @@ -3950,7 +4429,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -4210,7 +4761,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -4472,7 +5095,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -4760,7 +5455,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -5420,7 +6187,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -5672,7 +6511,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index 1f9c9cdff2c8d..6c165a6d49ed0 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/actionable-observability](https://github.com/orgs/elastic/team | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 123 | 0 | 123 | 0 | +| 126 | 0 | 126 | 0 | ## Common diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 3d5cf0c4d3b57..16b07a9464525 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 42410860f8c2d..97cf067aef9b2 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 12a6ce268fa97..d38fa14a5033e 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index fe995a3fedbcd..55aaa5b9e0f8f 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 26a6afce06fbb..565f08aeb6484 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 72cbbd5958ce6..4c00118d8efce 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 0f63847bb7ae8..c9e2bfb18c89f 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 56e928142e8aa..5966a4ad66ed6 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 19270a13cba30..ce1e8b2145e40 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 406f9e5ba0803..9c109c3543365 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 6f71c0b61d072..7baa4f79bad7a 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 5e99de070e633..8e4713f092395 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index 95e1987fd9dc2..ca766ad9e5f8e 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 182ff61fca757..bf2b7956baed7 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 00c7732b2dc8b..0660386b2bc95 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 210eee66113d9..d37b855985a98 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index ef103a7ce8de4..6f5686de24bd0 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 0e0aea36bce73..55718387c21d4 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index dbadd3ca9b1d2..ff7c81d96922d 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 395ff57494bc5..bdd3e1c5dd355 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index c36033cbb7304..06a48b3521db4 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index c468cacd790fd..309760d3dc9c3 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 5c977be1fc631..0c84033f1ba2d 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index 109850994103e..bdd6084a32efc 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -1885,6 +1885,30 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "kibanaReact", + "id": "def-public.useKibanaTheme", + "type": "Function", + "tags": [], + "label": "useKibanaTheme", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "@kbn/core-theme-browser", + "scope": "common", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-common.CoreTheme", + "text": "CoreTheme" + } + ], + "path": "src/plugins/kibana_react/public/theme/use_theme.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "kibanaReact", "id": "def-public.useUiSetting", diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index ef0925a8ca3f9..b464705b3805e 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 184 | 1 | 153 | 5 | +| 185 | 1 | 154 | 5 | ## Client diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 5702004618b43..1c34169f7a678 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 70b7260aaf7bf..4a423d9f04350 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index ae981db1be813..c2f213c20e516 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -6307,17 +6307,19 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderLayerHeader", + "id": "def-public.Visualization.LayerHeaderComponent", "type": "Function", "tags": [], - "label": "renderLayerHeader", + "label": "LayerHeaderComponent", "description": [ "\nHeader rendered as layer title. This can be used for both static and dynamic content like\nfor extra configurability, such as for switch chart type" ], "signature": [ - "((domElement: Element, props: ", + "((props: ", + "VisualizationLayerWidgetProps", + ") => React.ReactElement<", "VisualizationLayerWidgetProps", - ") => void | ((cleanupElement: Element) => void)) | undefined" + ", string | React.JSXElementConstructor> | null) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -6325,22 +6327,7 @@ "children": [ { "parentPluginId": "lens", - "id": "def-public.Visualization.renderLayerHeader.$1", - "type": "Object", - "tags": [], - "label": "domElement", - "description": [], - "signature": [ - "Element" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.renderLayerHeader.$2", + "id": "def-public.Visualization.LayerHeaderComponent.$1", "type": "CompoundType", "tags": [], "label": "props", @@ -6359,17 +6346,19 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderLayerPanel", + "id": "def-public.Visualization.LayerPanelComponent", "type": "Function", "tags": [], - "label": "renderLayerPanel", + "label": "LayerPanelComponent", "description": [ "\nLayer panel content rendered. This can be used to render a custom content below the title,\nlike a custom dataview switch" ], "signature": [ - "((domElement: Element, props: ", + "((props: ", "VisualizationLayerWidgetProps", - ") => void | ((cleanupElement: Element) => void)) | undefined" + ") => React.ReactElement<", + "VisualizationLayerWidgetProps", + ", string | React.JSXElementConstructor> | null) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -6377,22 +6366,7 @@ "children": [ { "parentPluginId": "lens", - "id": "def-public.Visualization.renderLayerPanel.$1", - "type": "Object", - "tags": [], - "label": "domElement", - "description": [], - "signature": [ - "Element" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.renderLayerPanel.$2", + "id": "def-public.Visualization.LayerPanelComponent.$1", "type": "CompoundType", "tags": [], "label": "props", @@ -6411,17 +6385,19 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderToolbar", + "id": "def-public.Visualization.ToolbarComponent", "type": "Function", "tags": [], - "label": "renderToolbar", + "label": "ToolbarComponent", "description": [ "\nToolbar rendered above the visualization. This is meant to be used to provide chart-level\nsettings for the visualization." ], "signature": [ - "((domElement: Element, props: ", + "((props: ", + "VisualizationToolbarProps", + ") => React.ReactElement<", "VisualizationToolbarProps", - ") => void | ((cleanupElement: Element) => void)) | undefined" + ", string | React.JSXElementConstructor> | null) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -6429,22 +6405,7 @@ "children": [ { "parentPluginId": "lens", - "id": "def-public.Visualization.renderToolbar.$1", - "type": "Object", - "tags": [], - "label": "domElement", - "description": [], - "signature": [ - "Element" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.renderToolbar.$2", + "id": "def-public.Visualization.ToolbarComponent.$1", "type": "Object", "tags": [], "label": "props", @@ -6758,15 +6719,17 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderLayerSettings", + "id": "def-public.Visualization.LayerSettingsComponent", "type": "Function", "tags": [], - "label": "renderLayerSettings", + "label": "LayerSettingsComponent", "description": [], "signature": [ - "((domElement: Element, props: ", + "((props: ", "VisualizationConfigProps", - " & { setState(newState: T | ((currState: T) => T)): void; panelRef: React.MutableRefObject; } & { section: \"data\" | \"appearance\"; }) => void | ((cleanupElement: Element) => void)) | undefined" + " & { setState(newState: T | ((currState: T) => T)): void; panelRef: React.MutableRefObject; } & { section: \"data\" | \"appearance\"; }) => React.ReactElement<", + "VisualizationLayerSettingsProps", + ", string | React.JSXElementConstructor> | null) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -6774,22 +6737,7 @@ "children": [ { "parentPluginId": "lens", - "id": "def-public.Visualization.renderLayerSettings.$1", - "type": "Object", - "tags": [], - "label": "domElement", - "description": [], - "signature": [ - "Element" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.renderLayerSettings.$2", + "id": "def-public.Visualization.LayerSettingsComponent.$1", "type": "CompoundType", "tags": [], "label": "props", @@ -6808,17 +6756,19 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionEditor", + "id": "def-public.Visualization.DimensionEditorComponent", "type": "Function", "tags": [], - "label": "renderDimensionEditor", + "label": "DimensionEditorComponent", "description": [ "\nAdditional editor that gets rendered inside the dimension popover in the \"appearance\" section.\nThis can be used to configure dimension-specific options" ], "signature": [ - "((domElement: Element, props: ", + "((props: ", + "VisualizationDimensionEditorProps", + ") => React.ReactElement<", "VisualizationDimensionEditorProps", - ") => void | ((cleanupElement: Element) => void)) | undefined" + ", string | React.JSXElementConstructor> | null) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -6826,22 +6776,7 @@ "children": [ { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionEditor.$1", - "type": "Object", - "tags": [], - "label": "domElement", - "description": [], - "signature": [ - "Element" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionEditor.$2", + "id": "def-public.Visualization.DimensionEditorComponent.$1", "type": "CompoundType", "tags": [], "label": "props", @@ -6860,17 +6795,19 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionEditorAdditionalSection", + "id": "def-public.Visualization.DimensionEditorAdditionalSectionComponent", "type": "Function", "tags": [], - "label": "renderDimensionEditorAdditionalSection", + "label": "DimensionEditorAdditionalSectionComponent", "description": [ "\nAdditional editor that gets rendered inside the dimension popover in an additional section below \"appearance\".\nThis can be used to configure dimension-specific options" ], "signature": [ - "((domElement: Element, props: ", + "((props: ", "VisualizationDimensionEditorProps", - ") => void | ((cleanupElement: Element) => void)) | undefined" + ") => React.ReactElement<", + "VisualizationDimensionEditorProps", + ", string | React.JSXElementConstructor> | null) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -6878,22 +6815,7 @@ "children": [ { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionEditorAdditionalSection.$1", - "type": "Object", - "tags": [], - "label": "domElement", - "description": [], - "signature": [ - "Element" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionEditorAdditionalSection.$2", + "id": "def-public.Visualization.DimensionEditorAdditionalSectionComponent.$1", "type": "CompoundType", "tags": [], "label": "props", @@ -6912,17 +6834,19 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionEditorDataExtra", + "id": "def-public.Visualization.DimensionEditorDataExtraComponent", "type": "Function", "tags": [], - "label": "renderDimensionEditorDataExtra", + "label": "DimensionEditorDataExtraComponent", "description": [ "\nAdditional editor that gets rendered inside the data section.\nThis can be used to configure dimension-specific options" ], "signature": [ - "((domElement: Element, props: ", + "((props: ", + "VisualizationDimensionEditorProps", + ") => React.ReactElement<", "VisualizationDimensionEditorProps", - ") => void | ((cleanupElement: Element) => void)) | undefined" + ", string | React.JSXElementConstructor> | null) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -6930,22 +6854,7 @@ "children": [ { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionEditorDataExtra.$1", - "type": "Object", - "tags": [], - "label": "domElement", - "description": [], - "signature": [ - "Element" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionEditorDataExtra.$2", + "id": "def-public.Visualization.DimensionEditorDataExtraComponent.$1", "type": "CompoundType", "tags": [], "label": "props", @@ -6964,15 +6873,15 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionTrigger", + "id": "def-public.Visualization.DimensionTriggerComponent", "type": "Function", "tags": [], - "label": "renderDimensionTrigger", + "label": "DimensionTriggerComponent", "description": [ "\nRenders dimension trigger. Used only for noDatasource layers" ], "signature": [ - "((props: { columnId: string; label: string; hideTooltip?: boolean | undefined; }) => JSX.Element | null) | undefined" + "((props: { columnId: string; label: string; hideTooltip?: boolean | undefined; }) => React.ReactElement<{ columnId: string; label: string; hideTooltip?: boolean | undefined; }, string | React.JSXElementConstructor> | null) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -6980,7 +6889,7 @@ "children": [ { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionTrigger.$1", + "id": "def-public.Visualization.DimensionTriggerComponent.$1", "type": "Object", "tags": [], "label": "props", @@ -6991,7 +6900,7 @@ "children": [ { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionTrigger.$1.columnId", + "id": "def-public.Visualization.DimensionTriggerComponent.$1.columnId", "type": "string", "tags": [], "label": "columnId", @@ -7002,7 +6911,7 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionTrigger.$1.label", + "id": "def-public.Visualization.DimensionTriggerComponent.$1.label", "type": "string", "tags": [], "label": "label", @@ -7013,7 +6922,7 @@ }, { "parentPluginId": "lens", - "id": "def-public.Visualization.renderDimensionTrigger.$1.hideTooltip", + "id": "def-public.Visualization.DimensionTriggerComponent.$1.hideTooltip", "type": "CompoundType", "tags": [], "label": "hideTooltip", @@ -7038,21 +6947,7 @@ "label": "getAddLayerButtonComponent", "description": [], "signature": [ - "((props: { supportedLayers: ", - "VisualizationLayerDescription", - "[]; addLayer: ", - "AddLayerFunction", - "; ensureIndexPattern: (specOrId: string | ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" - }, - ") => Promise; registerLibraryAnnotationGroup: ", - "RegisterLibraryAnnotationGroupFunction", - "; }) => JSX.Element | null) | undefined" + "((props: AddLayerButtonProps) => React.ReactElement> | null) | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, @@ -7065,181 +6960,13 @@ "tags": [], "label": "props", "description": [], + "signature": [ + "AddLayerButtonProps" + ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, "trackAdoption": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-public.Visualization.getAddLayerButtonComponent.$1.supportedLayers", - "type": "Array", - "tags": [], - "label": "supportedLayers", - "description": [], - "signature": [ - "VisualizationLayerDescription", - "[]" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.getAddLayerButtonComponent.$1.addLayer", - "type": "Function", - "tags": [], - "label": "addLayer", - "description": [], - "signature": [ - "(layerType: ", - "LayerType", - ", extraArg?: unknown, ignoreInitialValues?: boolean | undefined) => void" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "lens", - "id": "def-public.Visualization.getAddLayerButtonComponent.$1.addLayer.$1", - "type": "CompoundType", - "tags": [], - "label": "layerType", - "description": [], - "signature": [ - "\"data\" | \"annotations\" | \"metricTrendline\" | \"referenceLine\"" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.getAddLayerButtonComponent.$1.addLayer.$2", - "type": "Uncategorized", - "tags": [], - "label": "extraArg", - "description": [], - "signature": [ - "T | undefined" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.getAddLayerButtonComponent.$1.addLayer.$3", - "type": "CompoundType", - "tags": [], - "label": "ignoreInitialValues", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false - } - ] - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.getAddLayerButtonComponent.$1.ensureIndexPattern", - "type": "Function", - "tags": [], - "label": "ensureIndexPattern", - "description": [], - "signature": [ - "(specOrId: string | ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" - }, - ") => Promise" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-public.Visualization.getAddLayerButtonComponent.$1.ensureIndexPattern.$1", - "type": "CompoundType", - "tags": [], - "label": "specOrId", - "description": [], - "signature": [ - "string | ", - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewSpec", - "text": "DataViewSpec" - } - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "lens", - "id": "def-public.Visualization.getAddLayerButtonComponent.$1.registerLibraryAnnotationGroup", - "type": "Function", - "tags": [], - "label": "registerLibraryAnnotationGroup", - "description": [], - "signature": [ - "(groupInfo: { id: string; group: ", - { - "pluginId": "eventAnnotation", - "scope": "common", - "docId": "kibEventAnnotationPluginApi", - "section": "def-common.EventAnnotationGroupConfig", - "text": "EventAnnotationGroupConfig" - }, - "; }) => void" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "lens", - "id": "def-public.Visualization.getAddLayerButtonComponent.$1.registerLibraryAnnotationGroup.$1", - "type": "Object", - "tags": [], - "label": "groupInfo", - "description": [], - "signature": [ - "{ id: string; group: ", - { - "pluginId": "eventAnnotation", - "scope": "common", - "docId": "kibEventAnnotationPluginApi", - "section": "def-common.EventAnnotationGroupConfig", - "text": "EventAnnotationGroupConfig" - }, - "; }" - ], - "path": "x-pack/plugins/lens/public/types.ts", - "deprecated": false, - "trackAdoption": false - } - ] - } - ] + "isRequired": true } ], "returnComment": [] diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 72ecb5ec9adf9..ca3a17b212147 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 632 | 0 | 535 | 61 | +| 616 | 0 | 519 | 61 | ## Client diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 807b344d09d71..e7b946b57668b 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 2f938813a7cf5..9e6ec15925d00 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index c50892ecfc9fb..a82a67e24eed6 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 044a94e0981ab..3e230a7653c39 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index e8df9e3c7d2a7..8670a738e106e 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 10947cac40cd5..b4109301d5b55 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index aa39928764c40..d7aca74817758 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 012d41ab31d74..c95da1dc614df 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 80f89f9bf88ff..c5ad4831deb32 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index d79c1c2c5afd0..b6ee531e9af83 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index ba0f346cec1d3..e1c8e4815a99e 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 246e10b110691..b6a2326cfe82c 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index fafe457430ed5..25b3372bd7a9f 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 226b01f8662c6..5aa1d602b6700 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 981ab87527f1b..0076733c05cdd 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -8339,7 +8339,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; }>; }> | undefined; handler: ({}: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; }>; }> | undefined; handler: ({}: ", { "pluginId": "observability", "scope": "server", @@ -8347,7 +8419,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { body: { indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; }; }; }) => Promise<{ date: string; sliValue: number; }[]>; } & ", + " & { params: { body: { indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; }; }; }) => Promise<{ date: string; sliValue: number; }[]>; } & ", { "pluginId": "observability", "scope": "server", @@ -8425,7 +8497,7 @@ "section": "def-common.SavedObject", "text": "SavedObject" }, - "<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }>; sloTransformStats: ", + "<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }>; sloTransformStats: ", "TransformGetTransformStatsResponse", "; dataSample: string | ", "SearchResponse", @@ -8619,7 +8691,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -8709,7 +8853,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { path: { id: string; }; body: { name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | undefined; timeWindow?: { duration: ", + " & { params: { path: { id: string; }; body: { name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; } | undefined; timeWindow?: { duration: ", { "pluginId": "@kbn/slo-schema", "scope": "common", @@ -8749,7 +8893,7 @@ "section": "def-common.Duration", "text": "Duration" }, - " | undefined; } | undefined; tags?: string[] | undefined; }; }; }) => Promise<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }>; } & ", + " | undefined; } | undefined; tags?: string[] | undefined; }; }; }) => Promise<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }>; } & ", { "pluginId": "observability", "scope": "server", @@ -8771,7 +8915,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { path: { id: string; }; }; }) => Promise<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; }>; } & ", + " & { params: { path: { id: string; }; }; }) => Promise<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; }>; } & ", { "pluginId": "observability", "scope": "server", @@ -8811,7 +8955,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params?: { query?: { name?: string | undefined; indicatorTypes?: string[] | undefined; page?: string | undefined; perPage?: string | undefined; sortBy?: \"creationTime\" | \"indicatorType\" | undefined; sortDirection?: \"asc\" | \"desc\" | undefined; } | undefined; } | undefined; }) => Promise<{ page: number; perPage: number; total: number; results: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; })[]; }>; } & ", + " & { params?: { query?: { name?: string | undefined; indicatorTypes?: string[] | undefined; page?: string | undefined; perPage?: string | undefined; sortBy?: \"creationTime\" | \"indicatorType\" | undefined; sortDirection?: \"asc\" | \"desc\" | undefined; } | undefined; } | undefined; }) => Promise<{ page: number; perPage: number; total: number; results: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; })[]; }>; } & ", { "pluginId": "observability", "scope": "server", @@ -9067,7 +9211,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -9161,7 +9377,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { body: { name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: ", + " & { params: { body: { name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: ", { "pluginId": "@kbn/slo-schema", "scope": "common", @@ -9957,7 +10173,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; }>; }> | undefined; handler: ({}: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; }>; }> | undefined; handler: ({}: ", { "pluginId": "observability", "scope": "server", @@ -9965,7 +10253,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { body: { indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; }; }; }) => Promise<{ date: string; sliValue: number; }[]>; } & ", + " & { params: { body: { indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; }; }; }) => Promise<{ date: string; sliValue: number; }[]>; } & ", { "pluginId": "observability", "scope": "server", @@ -10043,7 +10331,7 @@ "section": "def-common.SavedObject", "text": "SavedObject" }, - "<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }>; sloTransformStats: ", + "<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; settings: { syncDelay: string; frequency: string; }; revision: number; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }>; sloTransformStats: ", "TransformGetTransformStatsResponse", "; dataSample: string | ", "SearchResponse", @@ -10237,7 +10525,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -10327,7 +10687,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { path: { id: string; }; body: { name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | undefined; timeWindow?: { duration: ", + " & { params: { path: { id: string; }; body: { name?: string | undefined; description?: string | undefined; indicator?: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; } | undefined; timeWindow?: { duration: ", { "pluginId": "@kbn/slo-schema", "scope": "common", @@ -10367,7 +10727,7 @@ "section": "def-common.Duration", "text": "Duration" }, - " | undefined; } | undefined; tags?: string[] | undefined; }; }; }) => Promise<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }>; } & ", + " | undefined; } | undefined; tags?: string[] | undefined; }; }; }) => Promise<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; }>; } & ", { "pluginId": "observability", "scope": "server", @@ -10389,7 +10749,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { path: { id: string; }; }; }) => Promise<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; }>; } & ", + " & { params: { path: { id: string; }; }; }) => Promise<{ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; }>; } & ", { "pluginId": "observability", "scope": "server", @@ -10429,7 +10789,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params?: { query?: { name?: string | undefined; indicatorTypes?: string[] | undefined; page?: string | undefined; perPage?: string | undefined; sortBy?: \"creationTime\" | \"indicatorType\" | undefined; sortDirection?: \"asc\" | \"desc\" | undefined; } | undefined; } | undefined; }) => Promise<{ page: number; perPage: number; total: number; results: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; })[]; }>; } & ", + " & { params?: { query?: { name?: string | undefined; indicatorTypes?: string[] | undefined; page?: string | undefined; perPage?: string | undefined; sortBy?: \"creationTime\" | \"indicatorType\" | undefined; sortDirection?: \"asc\" | \"desc\" | undefined; } | undefined; } | undefined; }) => Promise<{ page: number; perPage: number; total: number; results: ({ id: string; name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: string; type: \"rolling\"; } | { duration: string; type: \"calendarAligned\"; }; budgetingMethod: \"occurrences\" | \"timeslices\"; objective: { target: number; } & { timesliceTarget?: number | undefined; timesliceWindow?: string | undefined; }; revision: number; settings: { syncDelay: string; frequency: string; }; enabled: boolean; tags: string[]; createdAt: string; updatedAt: string; } & { summary: { status: \"HEALTHY\" | \"NO_DATA\" | \"DEGRADING\" | \"VIOLATED\"; sliValue: number; errorBudget: { initial: number; consumed: number; remaining: number; isEstimated: boolean; }; }; })[]; }>; } & ", { "pluginId": "observability", "scope": "server", @@ -10685,7 +11045,79 @@ "StringC", "; }>; timestampField: ", "StringC", - "; }>; }>]>; timeWindow: ", + "; }>; }>, ", + "TypeC", + "<{ type: ", + "LiteralC", + "<\"sli.histogram.custom\">; params: ", + "TypeC", + "<{ index: ", + "StringC", + "; timestampField: ", + "StringC", + "; filter: ", + "StringC", + "; good: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; total: ", + "UnionC", + "<[", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"value_count\">; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>, ", + "IntersectionC", + "<[", + "TypeC", + "<{ field: ", + "StringC", + "; aggregation: ", + "LiteralC", + "<\"range\">; from: ", + "NumberC", + "; to: ", + "NumberC", + "; }>, ", + "PartialC", + "<{ filter: ", + "StringC", + "; }>]>]>; }>; }>]>; timeWindow: ", "UnionC", "<[", "TypeC", @@ -10779,7 +11211,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { body: { name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; }; timeWindow: { duration: ", + " & { params: { body: { name: string; description: string; indicator: { type: \"sli.apm.transactionDuration\"; params: { environment: string; service: string; transactionType: string; transactionName: string; threshold: number; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.apm.transactionErrorRate\"; params: { environment: string; service: string; transactionType: string; transactionName: string; index: string; } & { filter?: string | undefined; }; } | { type: \"sli.kql.custom\"; params: { index: string; filter: string; good: string; total: string; timestampField: string; }; } | { type: \"sli.metric.custom\"; params: { index: string; filter: string; good: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; total: { metrics: ({ name: string; aggregation: \"sum\"; field: string; } & { filter?: string | undefined; })[]; equation: string; }; timestampField: string; }; } | { type: \"sli.histogram.custom\"; params: { index: string; timestampField: string; filter: string; good: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); total: ({ field: string; aggregation: \"value_count\"; } & { filter?: string | undefined; }) | ({ field: string; aggregation: \"range\"; from: number; to: number; } & { filter?: string | undefined; }); }; }; timeWindow: { duration: ", { "pluginId": "@kbn/slo-schema", "scope": "common", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 0df234b96e79e..fbc3508958587 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index 35be2c0504589..c78f74d6c882f 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index ff2fde96c61a7..2ce1737186d28 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index c2296ae53db1e..dd616dc2663f3 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 861834a9c4f7f..98e72930d470c 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,13 +21,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 71456 | 554 | 61247 | 1448 | +| 71406 | 554 | 61219 | 1452 | ## Plugin Directory | Plugin name           | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 271 | 10 | 266 | 27 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 272 | 10 | 267 | 27 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 36 | 1 | 32 | 2 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 45 | 0 | 27 | 1 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 795 | 1 | 765 | 48 | @@ -56,13 +56,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 271 | 0 | 252 | 1 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 100 | 0 | 98 | 9 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 54 | 0 | 51 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3303 | 119 | 2583 | 27 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3291 | 119 | 2571 | 27 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin provides the ability to create data views via a modal flyout inside Kibana apps | 16 | 0 | 7 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Reusable data view field editor across Kibana | 72 | 0 | 33 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data view management app | 2 | 0 | 2 | 0 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 1052 | 0 | 268 | 2 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 1009 | 0 | 243 | 2 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 28 | 3 | 24 | 0 | -| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 10 | 0 | 8 | 2 | +| | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 12 | 0 | 10 | 3 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 97 | 0 | 71 | 14 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | discoverLogExplorer | [@elastic/infra-monitoring-ui](https://github.com/orgs/elastic/teams/infra-monitoring-ui) | This plugin exposes and registers Logs+ features. | 0 | 0 | 0 | 0 | @@ -112,11 +112,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 123 | 2 | 96 | 4 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides UI and APIs for the interactive setup mode. | 28 | 0 | 18 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 6 | 0 | 6 | 0 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 184 | 1 | 153 | 5 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 185 | 1 | 154 | 5 | | kibanaUsageCollection | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 609 | 3 | 416 | 9 | | | [@elastic/sec-cloudnative-integrations](https://github.com/orgs/elastic/teams/sec-cloudnative-integrations) | - | 5 | 0 | 5 | 1 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 632 | 0 | 535 | 61 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 616 | 0 | 519 | 61 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 8 | 0 | 8 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | @@ -150,7 +150,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 154 | 0 | 140 | 2 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 79 | 0 | 73 | 3 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 100 | 0 | 52 | 1 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the definition and helper methods around saved searches, used by discover and visualizations. | 59 | 0 | 58 | 2 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the definition and helper methods around saved searches, used by discover and visualizations. | 62 | 0 | 61 | 3 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 32 | 0 | 13 | 0 | | | [@elastic/kibana-reporting-services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 8 | 5 | | searchprofiler | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | @@ -168,7 +168,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 14 | 0 | 14 | 3 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 4 | 0 | 4 | 1 | | synthetics | [@elastic/uptime](https://github.com/orgs/elastic/teams/uptime) | This plugin visualizes data from Synthetics and Heartbeat, and integrates with other Observability solutions. | 0 | 0 | 0 | 0 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 85 | 0 | 43 | 6 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 96 | 0 | 53 | 6 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 45 | 0 | 1 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 31 | 0 | 26 | 6 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 1 | 0 | 1 | 0 | @@ -178,7 +178,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 257 | 1 | 213 | 22 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [@elastic/kibana-localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 548 | 11 | 522 | 50 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 560 | 11 | 534 | 50 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Adds UI Actions service to Kibana | 144 | 2 | 102 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Extends UI Actions plugin with more functionality | 206 | 0 | 140 | 9 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | The `unifiedHistogram` plugin provides UI components to create a layout including a resizable histogram and a main display. | 53 | 0 | 23 | 2 | @@ -314,7 +314,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 22 | 0 | 7 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 3 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 7 | 0 | 7 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 26 | 6 | 26 | 1 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 26 | 6 | 26 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 13 | 0 | 13 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 447 | 1 | 178 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 58 | 0 | 52 | 6 | @@ -425,11 +425,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 27 | 2 | 24 | 0 | | | [@elastic/docs](https://github.com/orgs/elastic/teams/docs) | - | 72 | 0 | 72 | 2 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 1 | 0 | 1 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 52 | 0 | 34 | 4 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 39 | 0 | 26 | 5 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 19 | 0 | 11 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 35125 | 0 | 34718 | 0 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 13 | 2 | 5 | 0 | -| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 83 | 4 | 64 | 3 | +| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 84 | 4 | 65 | 3 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 4 | 0 | 4 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 27 | 0 | 14 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 7 | 0 | 3 | 0 | @@ -572,7 +572,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 0 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 15 | 0 | 4 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 9 | 0 | 3 | 0 | -| | [@elastic/actionable-observability](https://github.com/orgs/elastic/teams/actionable-observability) | - | 123 | 0 | 123 | 0 | +| | [@elastic/actionable-observability](https://github.com/orgs/elastic/teams/actionable-observability) | - | 126 | 0 | 126 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 20 | 0 | 12 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 102 | 2 | 65 | 1 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 4 | 0 | 2 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 14cf35d491244..306d81a66c57c 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 42932a9e4ed80..10bf8465201bc 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index d2e865f3ec499..8fc007f26d583 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 7822cb88b6009..708ac22b536eb 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx index 50fbbc3a61c3b..6b9e8c088933c 100644 --- a/api_docs/reporting_export_types.mdx +++ b/api_docs/reporting_export_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reportingExportTypes title: "reportingExportTypes" image: https://source.unsplash.com/400x175/?github description: API docs for the reportingExportTypes plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] --- import reportingExportTypesObj from './reporting_export_types.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 09326f46cbc88..55aaf7fb49561 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index f41dfe2655552..b2e08dbfc5ae8 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 11ed4001e0a05..bf5d42ca09b5a 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index b6b794f37e36d..a415a7115c42f 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index d1a10ab1a6a12..8ee7adf6c6294 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index f88eb3100ad74..1cd3c19ccf1a0 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 94741be4c27f0..0e0cbc78e84a7 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 80be972b77ca3..2d1d73970d0aa 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.devdocs.json b/api_docs/saved_search.devdocs.json index 8d6b6c28b3455..76ccee3737299 100644 --- a/api_docs/saved_search.devdocs.json +++ b/api_docs/saved_search.devdocs.json @@ -215,9 +215,9 @@ "(savedSearchId: string) => Promise<", { "pluginId": "savedSearch", - "scope": "public", + "scope": "common", "docId": "kibSavedSearchPluginApi", - "section": "def-public.SavedSearch", + "section": "def-common.SavedSearch", "text": "SavedSearch" }, ">" @@ -255,9 +255,9 @@ "() => ", { "pluginId": "savedSearch", - "scope": "public", + "scope": "common", "docId": "kibSavedSearchPluginApi", - "section": "def-public.SavedSearch", + "section": "def-common.SavedSearch", "text": "SavedSearch" } ], @@ -543,6 +543,66 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "savedSearch", + "id": "def-common.getKibanaContextFn", + "type": "Function", + "tags": [], + "label": "getKibanaContextFn", + "description": [], + "signature": [ + "(getStartDependencies: (getKibanaRequest: (() => ", + { + "pluginId": "@kbn/core-http-server", + "scope": "common", + "docId": "kibKbnCoreHttpServerPluginApi", + "section": "def-common.KibanaRequest", + "text": "KibanaRequest" + }, + ") | undefined) => Promise<", + "KibanaContextStartDependencies", + ">) => ", + { + "pluginId": "data", + "scope": "common", + "docId": "kibDataSearchPluginApi", + "section": "def-common.ExpressionFunctionKibanaContext", + "text": "ExpressionFunctionKibanaContext" + } + ], + "path": "src/plugins/saved_search/common/expressions/kibana_context.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "savedSearch", + "id": "def-common.getKibanaContextFn.$1", + "type": "Function", + "tags": [], + "label": "getStartDependencies", + "description": [], + "signature": [ + "(getKibanaRequest: (() => ", + { + "pluginId": "@kbn/core-http-server", + "scope": "common", + "docId": "kibKbnCoreHttpServerPluginApi", + "section": "def-common.KibanaRequest", + "text": "KibanaRequest" + }, + ") | undefined) => Promise<", + "KibanaContextStartDependencies", + ">" + ], + "path": "src/plugins/saved_search/common/expressions/kibana_context.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "savedSearch", "id": "def-common.getSavedSearchFullPathUrl", @@ -1230,6 +1290,20 @@ "path": "src/plugins/saved_search/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "savedSearch", + "id": "def-common.SavedSearch.sharingSavedObjectProps", + "type": "Object", + "tags": [], + "label": "sharingSavedObjectProps", + "description": [], + "signature": [ + "{ outcome?: \"conflict\" | \"exactMatch\" | \"aliasMatch\" | undefined; aliasTargetId?: string | undefined; aliasPurpose?: \"savedObjectConversion\" | \"savedObjectImport\" | undefined; errorJSON?: string | undefined; } | undefined" + ], + "path": "src/plugins/saved_search/common/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index 5ff2525befc92..dc3a6d2e7062f 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 59 | 0 | 58 | 2 | +| 62 | 0 | 61 | 3 | ## Client diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 95eb192757cd7..9ce5e1a764c9a 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 67ccdec43f18d..3336908f92a4b 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index d53656488d71e..93c3c34ab3f3a 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index a2dd6299f4432..12c96b0489eb1 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index 6efeae824099e..4b075c96b93cb 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index 1421bdeda5eae..c0bd2276b506b 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index a21c5c4898d1b..3857f83fd5316 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index 7f8d4d13d0d94..2325827a0fde5 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index f46a38f4d7d4b..acdbb7fafc901 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index fcef5450c2de9..01bb14d46455d 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 12e5f4ac28251..6fa1e15cdece0 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 7f9d27f773ff4..80b510f41a538 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index ea29696210706..31ca31cdf0b20 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index bb499ac565567..e943e0ef99c01 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index 462ea3091965a..185c1e9e6751f 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.devdocs.json b/api_docs/task_manager.devdocs.json index 2f01601dbcc8a..abdde3e96fa97 100644 --- a/api_docs/task_manager.devdocs.json +++ b/api_docs/task_manager.devdocs.json @@ -336,6 +336,40 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "taskManager", + "id": "def-server.createSkipError", + "type": "Function", + "tags": [], + "label": "createSkipError", + "description": [], + "signature": [ + "(error: Error) => ", + "DecoratedError" + ], + "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "taskManager", + "id": "def-server.createSkipError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "taskManager", "id": "def-server.isEphemeralTaskRejectedDueToCapacityError", @@ -372,6 +406,42 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "taskManager", + "id": "def-server.isSkipError", + "type": "Function", + "tags": [], + "label": "isSkipError", + "description": [], + "signature": [ + "(error: Error | ", + "DecoratedError", + ") => boolean" + ], + "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "taskManager", + "id": "def-server.isSkipError.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error | ", + "DecoratedError" + ], + "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "taskManager", "id": "def-server.isUnrecoverableError", @@ -408,6 +478,54 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "taskManager", + "id": "def-server.throwRetryableError", + "type": "Function", + "tags": [], + "label": "throwRetryableError", + "description": [], + "signature": [ + "(error: Error, shouldRetry: boolean | Date) => void" + ], + "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "taskManager", + "id": "def-server.throwRetryableError.$1", + "type": "Object", + "tags": [], + "label": "error", + "description": [], + "signature": [ + "Error" + ], + "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "taskManager", + "id": "def-server.throwRetryableError.$2", + "type": "CompoundType", + "tags": [], + "label": "shouldRetry", + "description": [], + "signature": [ + "boolean | Date" + ], + "path": "x-pack/plugins/task_manager/server/task_running/errors.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "taskManager", "id": "def-server.throwUnrecoverableError", @@ -1072,6 +1190,22 @@ "path": "x-pack/plugins/task_manager/server/task.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "taskManager", + "id": "def-server.TaskInstance.numSkippedRuns", + "type": "number", + "tags": [], + "label": "numSkippedRuns", + "description": [ + "\nIndicates the number of skipped executions." + ], + "signature": [ + "number | undefined" + ], + "path": "x-pack/plugins/task_manager/server/task.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -1156,7 +1290,16 @@ "text": "RunContext" }, ") => ", - "CancellableTask" + "CancellableTask", + "<", + { + "pluginId": "taskManager", + "scope": "server", + "docId": "kibTaskManagerPluginApi", + "section": "def-server.ConcreteTaskInstance", + "text": "ConcreteTaskInstance" + }, + ">" ], "path": "x-pack/plugins/task_manager/server/task_type_dictionary.ts", "deprecated": false, @@ -1238,6 +1381,48 @@ "path": "x-pack/plugins/task_manager/server/task_type_dictionary.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "taskManager", + "id": "def-server.TaskRegisterDefinition.paramsSchema", + "type": "Object", + "tags": [], + "label": "paramsSchema", + "description": [], + "signature": [ + { + "pluginId": "@kbn/config-schema", + "scope": "common", + "docId": "kibKbnConfigSchemaPluginApi", + "section": "def-common.ObjectType", + "text": "ObjectType" + }, + " | undefined" + ], + "path": "x-pack/plugins/task_manager/server/task_type_dictionary.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "taskManager", + "id": "def-server.TaskRegisterDefinition.indirectParamsSchema", + "type": "Object", + "tags": [], + "label": "indirectParamsSchema", + "description": [], + "signature": [ + { + "pluginId": "@kbn/config-schema", + "scope": "common", + "docId": "kibKbnConfigSchemaPluginApi", + "section": "def-common.ObjectType", + "text": "ObjectType" + }, + " | undefined" + ], + "path": "x-pack/plugins/task_manager/server/task_type_dictionary.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -1275,6 +1460,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "taskManager", + "id": "def-server.LoadIndirectParamsResult", + "type": "Type", + "tags": [], + "label": "LoadIndirectParamsResult", + "description": [], + "signature": [ + "{ data: T; error?: undefined; } | { data?: undefined; error: Error; }" + ], + "path": "x-pack/plugins/task_manager/server/task.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "taskManager", "id": "def-server.TaskDefinitionRegistry", @@ -1317,7 +1517,16 @@ "text": "RunContext" }, ") => ", - "CancellableTask" + "CancellableTask", + "<", + { + "pluginId": "taskManager", + "scope": "server", + "docId": "kibTaskManagerPluginApi", + "section": "def-server.ConcreteTaskInstance", + "text": "ConcreteTaskInstance" + }, + ">" ], "path": "x-pack/plugins/task_manager/server/task.ts", "deprecated": false, diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 0f1ea471ace90..1926397632e90 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 85 | 0 | 43 | 6 | +| 96 | 0 | 53 | 6 | ## Server diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index 7edbd703a0df2..ae3107d151d7b 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 299477c7911b1..2850f28186151 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 04f9f23159814..fb60260dcb0f9 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index dbb5a77449ee6..21619a7e4f452 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 9de156c444061..6d1497a9e8467 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index a27f81878b249..add2781d01761 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 9785e0055bb2a..5914d96331826 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 54eeb5d8c0a78..4c89c62e6ea5d 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index 553e899a822f7..1d182a1424ca6 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -1786,6 +1786,53 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.validateActionFilterQuery", + "type": "Function", + "tags": [], + "label": "validateActionFilterQuery", + "description": [], + "signature": [ + "(actionItem: ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleAction", + "text": "RuleAction" + }, + ") => string | null" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.validateActionFilterQuery.$1", + "type": "Object", + "tags": [], + "label": "actionItem", + "description": [], + "signature": [ + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.RuleAction", + "text": "RuleAction" + } + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.ValueExpression", @@ -9525,6 +9572,119 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES", + "type": "Object", + "tags": [], + "label": "NORMALIZED_FIELD_TYPES", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES.long", + "type": "string", + "tags": [], + "label": "long", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES.integer", + "type": "string", + "tags": [], + "label": "integer", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES.short", + "type": "string", + "tags": [], + "label": "short", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES.byte", + "type": "string", + "tags": [], + "label": "byte", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES.double", + "type": "string", + "tags": [], + "label": "double", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES.float", + "type": "string", + "tags": [], + "label": "float", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES.half_float", + "type": "string", + "tags": [], + "label": "half_float", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES.scaled_float", + "type": "string", + "tags": [], + "label": "scaled_float", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-common.NORMALIZED_FIELD_TYPES.unsigned_long", + "type": "string", + "tags": [], + "label": "unsigned_long", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/common/normalized_field_types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false } ] } diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 7b08d9e8dbc95..0a369a01c2498 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 548 | 11 | 522 | 50 | +| 560 | 11 | 534 | 50 | ## Client diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index ee48b3f51ddf2..2d8318890a7b2 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 108aa82a447c6..ea028e5eeada3 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index ad5c94fba4a36..6a7ff22ae4abb 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 88faa38d98e02..9231e118ab54c 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 8d4c0c4bf983e..953b50622412e 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 24f9fd66c1199..d8e713cc228e5 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index f42f52bdf4cbf..e53c2069d942a 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index f9fe336abe0fc..8f82b0dc42e40 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 668875cbcf430..80f9a0ec49405 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 7fda836aa6c80..120b8cc82afb2 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index c3b3c3b155e11..2102f45d75182 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index a7891dd202f29..5fe96186f9f78 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 8812c83c92731..562d6530b7256 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 94899c3809a6d..125994d58e028 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index 943e66dd5bd5e..53fa9cca7b44e 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index a937f16ad5720..e2a3e5465f526 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 48557d2c1158c..65693b98df616 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index c71d2ca9d461f..a7b12e70a4b31 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualization_ui_components.mdx b/api_docs/visualization_ui_components.mdx index 319362cb7ed79..f9d8116aa5a56 100644 --- a/api_docs/visualization_ui_components.mdx +++ b/api_docs/visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizationUiComponents title: "visualizationUiComponents" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizationUiComponents plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizationUiComponents'] --- import visualizationUiComponentsObj from './visualization_ui_components.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 87f8866bfef48..435359ae605d9 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-07-11 +date: 2023-07-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From cef5fd781713def624d7a0b2b02722688a2c553d Mon Sep 17 00:00:00 2001 From: Yngrid Coello Date: Wed, 12 Jul 2023 08:11:25 +0200 Subject: [PATCH 52/97] [APM] Overflow buckets doc updated with tilt information (#161640) --- .../apm/dev_docs/overflow_bucket_setup.md | 121 +++++++++++++++++- 1 file changed, 117 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/apm/dev_docs/overflow_bucket_setup.md b/x-pack/plugins/apm/dev_docs/overflow_bucket_setup.md index 46d9f4c6df72a..61e8bfb53d581 100644 --- a/x-pack/plugins/apm/dev_docs/overflow_bucket_setup.md +++ b/x-pack/plugins/apm/dev_docs/overflow_bucket_setup.md @@ -1,11 +1,124 @@ +# Table of contents +1. [Summary](#summary) +2. [Start stack using Tilt](#Tilt) +3. [Start stack manually](#manually) + ## Summary 8.7 introduced Overflow Buckets for Metrics. The below setup would enable generating the overflow buckets for the metrics indices. +## Start stack using Tilt + +With a 1GB server, MaxTransactionGroups is 5000 and MaxServices is 1000. Per-service max transaction groups is hardcoded as 10% of max transaction groups, i.e. 500. + ### Pre-requisites +1. Install golang and set go path properly +2. Clone [Apm-server](https://github.com/elastic/apm-server/tree/main) repository +3. Install [Docker](https://www.docker.com/products/docker-desktop/). +4. Install [Tilt](https://docs.tilt.dev/install.html). +5. Execute `tilt up` in the root of the repository. This will start an APM server, an es and a kibana for you. You can verify the status of the components accessing [http://localhost:10350/](http://localhost:10350/). -- Install golang and set go path properly +For more detailed instructions you can check [apm-server dev documentation](https://github.com/elastic/apm-server/blob/main/dev_docs/TESTING.md#tilt--kubernetes). + +### Steps to generate data +- Copy paste the below script in a file called `load_generator.go` +
+ load_generator.go + + ```go + package main + + import ( + "fmt" + "os" + "strconv" + "time" + + "go.elastic.co/apm/v2" + ) + + func main() { + tracer := apm.DefaultTracer() + g, err := strconv.Atoi(os.Getenv("TXGROUPS")) + if err != nil { + panic(err) + } + for i := g; i >= 1; i-- { + once(tracer, fmt.Sprintf("type%d", i)) + time.Sleep(time.Millisecond) + } + tracer.Flush(nil) + fmt.Println("ok finished publishing ", g) + } + + func once(tracer *apm.Tracer, name string) { + tx := tracer.StartTransaction("txname", name) + defer tx.End() + + span := tx.StartSpanOptions(name, "type", apm.SpanOptions{}) + time.Sleep(time.Millisecond * 1) + + span.Outcome = "success" + span.Context.SetDestinationService(apm.DestinationServiceSpanContext{ + Resource: fmt.Sprintf("dest_resource"), + }) + span.End() + } + ``` +
+ +#### Overflow buckets for transactions +- Create a Bash Script file in order to test overflow bucket with transactions, name it anything - e.g., `generator_tx_max.sh`. Note that this test will generate 600 TxGroups which exceeds the known limit of 500 +
+ generator_tx_max.sh + + ```sh + #!/usr/bin/env bash + + echo "Starting script" + + go build -o load-generator load-generator.go || exit 1 + + ELASTIC_APM_SERVICE_NAME="fixed" TXGROUPS="600" ./load-generator & + + wait + echo "Ending script" + ``` +
+ +- Run `sh generator_tx_max` to generate the data + +#### Overflow buckets for services +- Create a Bash Script file in order to test overflow bucket with transactions, name it anything - e.g., `generator_service_max.sh`. Note that this test will generate 2000 services which exceeds the known limit of 1000 +
+ generator_service_max.sh + + ```sh + #!/usr/bin/env bash + + echo "Starting script" + + go build -o load-generator load-generator.go || exit 1 + + for i in {1..2000} + do + ELASTIC_APM_SERVICE_NAME="random$i" TXGROUPS="5" ./load-generator & + done + + wait + + echo "Ending script" + ``` +
+ +- Run `sh generator_service_max` to generate the data + +## Start stack manually + +### Pre-requisites + +- Install golang and set go path properly - Run Elasticsearch locally ``` yarn es snapshot @@ -19,7 +132,7 @@ git clone git@github.com:[USER]/apm-server.git ``` - Modify `apm-server.yml` accordingly - ``` + ```yml ## Add this to the bottom of the file apm-server.aggregation: service_transactions: @@ -75,7 +188,7 @@ - Now create a Bash Script file, name it anything - e.g., `service_max_group.sh` This file will generate services and then transactions for each service using the go script above. - ``` + ```sh #!/usr/bin/env bash echo "Starting script" @@ -95,7 +208,7 @@ This would start generating events to APM Server. Now open Service Inventory Page on Kibana to observe the `_other` bucket. -## Known Issues +### Known Issues - APM Server is unable to use Fleet API to generate APM Indices. Due to this, when starting the APM Server, you will see errors like unable to find Metrics Indices. To fix this, run one of the Synthtrace Scenario files which would create the required indices. ``` From 85a99c954f386bfa6291b266fe94a1456e312b25 Mon Sep 17 00:00:00 2001 From: Dzmitry Lemechko Date: Wed, 12 Jul 2023 09:06:53 +0200 Subject: [PATCH 53/97] [ftr] migrate time picker GUI selection to uiSettings API call (#161642) closes #113998 In order to make FTR functional tests faster and less flaky, we started migrating time picker selection from UI action to Kibana API call: ``` await this.kibanaServer.uiSettings.update({ 'timepicker:timeDefaults': `{ "from": , "to": }`, }); ``` In this PR I updated most of the tests listed in the meta issue, so we can close it. Flaky test runner https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2606 --- .../apps/discover/group1/_filter_editor.ts | 3 ++- .../apps/visualize/group1/_data_table.ts | 15 +++++---------- .../apps/visualize/group3/_add_to_dashboard.ts | 12 ++++-------- .../apps/visualize/group3/_pie_chart.ts | 18 +++++------------- .../apps/visualize/group4/_tsvb_chart.ts | 6 ++++-- .../apps/visualize/group6/_tag_cloud.ts | 7 +++++-- .../replaced_vislib_chart_types/_area_chart.ts | 3 ++- .../_line_chart_split_chart.ts | 7 +++++-- .../_line_chart_split_series.ts | 7 +++++-- .../_point_series_options.ts | 7 +++++-- .../_vertical_bar_chart.ts | 16 ++++++++++++---- .../apps/discover/value_suggestions.ts | 2 ++ 12 files changed, 56 insertions(+), 47 deletions(-) diff --git a/test/functional/apps/discover/group1/_filter_editor.ts b/test/functional/apps/discover/group1/_filter_editor.ts index fdc21921833f4..7e338f553d940 100644 --- a/test/functional/apps/discover/group1/_filter_editor.ts +++ b/test/functional/apps/discover/group1/_filter_editor.ts @@ -34,9 +34,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // and load a set of makelogs data await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.uiSettings.replace(defaultSettings); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); log.debug('discover filter editor'); await PageObjects.common.navigateToApp('discover'); - await PageObjects.timePicker.setDefaultAbsoluteRange(); }); describe('filter editor', function () { @@ -169,6 +169,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await security.testUser.restoreDefaults(); + await PageObjects.common.unsetTime(); }); }); } diff --git a/test/functional/apps/visualize/group1/_data_table.ts b/test/functional/apps/visualize/group1/_data_table.ts index 19af7438fe202..90936b26808a8 100644 --- a/test/functional/apps/visualize/group1/_data_table.ts +++ b/test/functional/apps/visualize/group1/_data_table.ts @@ -29,13 +29,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async function () { await PageObjects.visualize.initTests(); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); log.debug('navigateToApp visualize'); await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickDataTable'); await PageObjects.visualize.clickDataTable(); log.debug('clickNewSearch'); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('Bucket = Split rows'); await PageObjects.visEditor.clickBucket('Split rows'); log.debug('Aggregation = Histogram'); @@ -47,6 +47,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visEditor.clickGo(); }); + after(async () => { + await PageObjects.common.unsetTime(); + }); + it('should allow applying changed params', async () => { await PageObjects.visEditor.setInterval('1', { type: 'numeric', append: true }); const interval = await PageObjects.visEditor.getNumericInterval(); @@ -131,7 +135,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('Split rows'); await PageObjects.visEditor.selectAggregation('Range'); await PageObjects.visEditor.selectField('bytes'); @@ -174,7 +177,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('Metric', 'metrics'); await PageObjects.visEditor.selectAggregation('Average Bucket', 'metrics'); await PageObjects.visEditor.selectAggregation('Terms', 'metrics', true); @@ -188,7 +190,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('Split rows'); await PageObjects.visEditor.selectAggregation('Date Histogram'); await PageObjects.visEditor.selectField('@timestamp'); @@ -206,7 +207,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('Split rows'); await PageObjects.visEditor.selectAggregation('Date Histogram'); await PageObjects.visEditor.selectField('UTC time'); @@ -244,7 +244,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickMetricEditor(); await PageObjects.visEditor.selectAggregation('Top Hit', 'metrics'); await PageObjects.visEditor.selectField('agent.raw', 'metrics'); @@ -258,7 +257,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('Split rows'); await PageObjects.visEditor.selectAggregation('Range'); await PageObjects.visEditor.selectField('bytes'); @@ -275,7 +273,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('Split rows'); await PageObjects.visEditor.selectAggregation('Terms'); await PageObjects.visEditor.selectField('extension.raw'); @@ -313,7 +310,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('Split rows'); await PageObjects.visEditor.selectAggregation('Terms'); await PageObjects.visEditor.selectField('extension.raw'); @@ -407,7 +403,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickDataTable(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('Split table'); // split by column to make all tables rows visible await PageObjects.visEditor.clickSplitDirection('Columns'); diff --git a/test/functional/apps/visualize/group3/_add_to_dashboard.ts b/test/functional/apps/visualize/group3/_add_to_dashboard.ts index 32d329cd181da..896826c2caa07 100644 --- a/test/functional/apps/visualize/group3/_add_to_dashboard.ts +++ b/test/functional/apps/visualize/group3/_add_to_dashboard.ts @@ -28,12 +28,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Add to Dashboard', function describeIndexTests() { before(async () => { await PageObjects.visualize.initTests(); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); + }); + after(async () => { + await PageObjects.common.unsetTime(); }); it('adding a new metric to a new dashboard by value', async function () { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await testSubjects.click('visualizeSaveButton'); @@ -57,7 +60,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await testSubjects.click('visualizeSaveButton'); @@ -83,7 +85,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await testSubjects.click('visualizeSaveButton'); @@ -122,7 +123,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await testSubjects.click('visualizeSaveButton'); @@ -169,7 +169,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await testSubjects.click('visualizeSaveButton'); @@ -200,7 +199,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await testSubjects.click('visualizeSaveButton'); @@ -233,7 +231,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await testSubjects.click('visualizeSaveButton'); @@ -279,7 +276,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickMetric(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await testSubjects.click('visualizeSaveButton'); diff --git a/test/functional/apps/visualize/group3/_pie_chart.ts b/test/functional/apps/visualize/group3/_pie_chart.ts index e971daa18c8cb..466c82227606f 100644 --- a/test/functional/apps/visualize/group3/_pie_chart.ts +++ b/test/functional/apps/visualize/group3/_pie_chart.ts @@ -35,10 +35,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('navigateToApp visualize'); await PageObjects.visualize.navigateToNewAggBasedVisualization(); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('select bucket Split slices'); await PageObjects.visEditor.clickBucket('Split slices'); log.debug('Click aggregation Histogram'); @@ -53,6 +53,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visEditor.clickGo(isNewChartsLibraryEnabled); }); + after(async () => { + await PageObjects.common.unsetTime(); + }); + it('should save and load', async function () { await PageObjects.visualize.saveVisualizationExpectSuccessAndBreadcrumb(vizName1); @@ -95,7 +99,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('select bucket Split slices'); await PageObjects.visEditor.clickBucket('Split slices'); log.debug('Click aggregation Terms'); @@ -293,7 +296,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('select bucket Split slices'); await PageObjects.visEditor.clickBucket('Split slices'); log.debug('Click aggregation Filters'); @@ -322,14 +324,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - log.debug( - 'Set absolute time range from "' + - PageObjects.timePicker.defaultStartTime + - '" to "' + - PageObjects.timePicker.defaultEndTime + - '"' - ); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('select bucket Split slices'); await PageObjects.visEditor.clickBucket('Split slices'); log.debug('Click aggregation Histogram'); @@ -459,7 +453,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickPieChart'); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('select bucket Split slices'); await PageObjects.visEditor.clickBucket('Split slices'); log.debug('Click aggregation Filters'); @@ -486,7 +479,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickPieChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('select bucket Split chart'); await PageObjects.visEditor.clickBucket('Split chart'); await PageObjects.visEditor.selectAggregation('Terms'); diff --git a/test/functional/apps/visualize/group4/_tsvb_chart.ts b/test/functional/apps/visualize/group4/_tsvb_chart.ts index aa66ca7ece7ab..02ebf6b32f85e 100644 --- a/test/functional/apps/visualize/group4/_tsvb_chart.ts +++ b/test/functional/apps/visualize/group4/_tsvb_chart.ts @@ -35,6 +35,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await common.setTime({ from, to }); }); + after(async () => { + await common.unsetTime(); + }); + beforeEach(async () => { await security.testUser.setRoles( ['kibana_admin', 'test_logstash_reader', 'kibana_sample_admin'], @@ -427,7 +431,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('switch panel interval test', () => { beforeEach(async () => { - await visualBuilder.setTime(); await visualBuilder.clickMetric(); await visualBuilder.checkMetricTabIsPresent(); await visualBuilder.clickPanelOptions('metric'); @@ -548,7 +551,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); beforeEach(async () => { - await visualBuilder.setTime(); await visualBuilder.selectAggType('Average'); await visualBuilder.setFieldForAggregation('bytes'); await visualBuilder.setMetricsGroupByTerms('machine.os.raw'); diff --git a/test/functional/apps/visualize/group6/_tag_cloud.ts b/test/functional/apps/visualize/group6/_tag_cloud.ts index d021e8b08d43a..e1f6109c49608 100644 --- a/test/functional/apps/visualize/group6/_tag_cloud.ts +++ b/test/functional/apps/visualize/group6/_tag_cloud.ts @@ -35,12 +35,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async function () { await PageObjects.visualize.initTests(); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); log.debug('navigateToApp visualize'); await PageObjects.visualize.navigateToNewAggBasedVisualization(); log.debug('clickTagCloud'); await PageObjects.visualize.clickTagCloud(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('select Tags'); await PageObjects.visEditor.clickBucket('Tags'); log.debug('Click aggregation Terms'); @@ -53,6 +53,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visEditor.clickGo(); }); + after(async () => { + await PageObjects.common.unsetTime(); + }); + it('should have inspector enabled', async function () { await inspector.expectIsEnabled(); }); @@ -161,7 +165,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { navigateToVisualize: false, }); await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visChart.waitForVisualization(); }); diff --git a/test/functional/apps/visualize/replaced_vislib_chart_types/_area_chart.ts b/test/functional/apps/visualize/replaced_vislib_chart_types/_area_chart.ts index 3e765baf3ba64..50f0988575750 100644 --- a/test/functional/apps/visualize/replaced_vislib_chart_types/_area_chart.ts +++ b/test/functional/apps/visualize/replaced_vislib_chart_types/_area_chart.ts @@ -33,6 +33,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('area charts', function indexPatternCreation() { before(async () => { await PageObjects.visualize.initTests(); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); }); const initAreaChart = async () => { log.debug('navigateToApp visualize'); @@ -41,7 +42,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.clickAreaChart(); log.debug('clickNewSearch'); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('Click X-axis'); await PageObjects.visEditor.clickBucket('X-axis'); log.debug('Click Date Histogram'); @@ -67,6 +67,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async function () { await security.testUser.restoreDefaults(); + await PageObjects.common.unsetTime(); }); it('should save and load with special characters', async function () { diff --git a/test/functional/apps/visualize/replaced_vislib_chart_types/_line_chart_split_chart.ts b/test/functional/apps/visualize/replaced_vislib_chart_types/_line_chart_split_chart.ts index ef7e3aa916d4a..ee0653c16fc8e 100644 --- a/test/functional/apps/visualize/replaced_vislib_chart_types/_line_chart_split_chart.ts +++ b/test/functional/apps/visualize/replaced_vislib_chart_types/_line_chart_split_chart.ts @@ -32,7 +32,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('Bucket = Split chart'); await PageObjects.visEditor.clickBucket('Split chart'); log.debug('Aggregation = Terms'); @@ -46,9 +45,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async () => { await PageObjects.visualize.initTests(); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); await initLineChart(); }); + after(async () => { + await PageObjects.common.unsetTime(); + }); + afterEach(async () => { await inspector.close(); }); @@ -242,7 +246,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); }); describe('parent pipeline', () => { diff --git a/test/functional/apps/visualize/replaced_vislib_chart_types/_line_chart_split_series.ts b/test/functional/apps/visualize/replaced_vislib_chart_types/_line_chart_split_series.ts index 8583220d76a5c..b15f264e144e1 100644 --- a/test/functional/apps/visualize/replaced_vislib_chart_types/_line_chart_split_series.ts +++ b/test/functional/apps/visualize/replaced_vislib_chart_types/_line_chart_split_series.ts @@ -32,7 +32,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('Bucket = Split chart'); await PageObjects.visEditor.clickBucket('Split series'); log.debug('Aggregation = Terms'); @@ -44,9 +43,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async () => { await PageObjects.visualize.initTests(); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); await initLineChart(); }); + after(async () => { + await PageObjects.common.unsetTime(); + }); + afterEach(async () => { await inspector.close(); }); @@ -240,7 +244,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); }); describe('parent pipeline', () => { diff --git a/test/functional/apps/visualize/replaced_vislib_chart_types/_point_series_options.ts b/test/functional/apps/visualize/replaced_vislib_chart_types/_point_series_options.ts index d093959f45405..6fdaa4d5a0189 100644 --- a/test/functional/apps/visualize/replaced_vislib_chart_types/_point_series_options.ts +++ b/test/functional/apps/visualize/replaced_vislib_chart_types/_point_series_options.ts @@ -33,7 +33,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickLineChart'); await PageObjects.visualize.clickLineChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('Bucket = X-axis'); await PageObjects.visEditor.clickBucket('X-axis'); log.debug('Aggregation = Date Histogram'); @@ -64,9 +63,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('point series', function describeIndexTests() { before(async () => { await PageObjects.visualize.initTests(); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); await initChart(); }); + after(async () => { + await PageObjects.common.unsetTime(); + }); + describe('secondary value axis', function () { it('should show correct chart', async function () { const expectedChartValues = [ @@ -158,7 +162,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('Bucket = X-axis'); await PageObjects.visEditor.clickBucket('X-axis'); log.debug('Aggregation = Terms'); diff --git a/test/functional/apps/visualize/replaced_vislib_chart_types/_vertical_bar_chart.ts b/test/functional/apps/visualize/replaced_vislib_chart_types/_vertical_bar_chart.ts index 12a7f62a2801d..6e5d26d52f6e8 100644 --- a/test/functional/apps/visualize/replaced_vislib_chart_types/_vertical_bar_chart.ts +++ b/test/functional/apps/visualize/replaced_vislib_chart_types/_vertical_bar_chart.ts @@ -16,13 +16,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const inspector = getService('inspector'); const testSubjects = getService('testSubjects'); const filterBar = getService('filterBar'); - const PageObjects = getPageObjects(['visualize', 'visEditor', 'visChart', 'timePicker']); + const PageObjects = getPageObjects([ + 'visualize', + 'visEditor', + 'visChart', + 'timePicker', + 'common', + ]); const xyChartSelector = 'xyVisChart'; describe('vertical bar chart', function () { before(async () => { await PageObjects.visualize.initTests(); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); + }); + + after(async () => { + await PageObjects.common.unsetTime(); }); const vizName1 = 'Visualization VerticalBarChart'; @@ -33,7 +44,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { log.debug('clickVerticalBarChart'); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); log.debug('Bucket = X-Axis'); await PageObjects.visEditor.clickBucket('X-axis'); log.debug('Aggregation = Date Histogram'); @@ -64,7 +74,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('X-axis'); await PageObjects.visEditor.selectAggregation('Date Range'); await PageObjects.visEditor.selectField('@timestamp'); @@ -88,7 +97,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualize.navigateToNewAggBasedVisualization(); await PageObjects.visualize.clickVerticalBarChart(); await PageObjects.visualize.clickNewSearch(); - await PageObjects.timePicker.setDefaultAbsoluteRange(); await PageObjects.visEditor.clickBucket('X-axis'); log.debug('Aggregation = Date Range'); await PageObjects.visEditor.selectAggregation('Date Range'); diff --git a/x-pack/test/functional/apps/discover/value_suggestions.ts b/x-pack/test/functional/apps/discover/value_suggestions.ts index 41d1b071b6b0d..8d0c0ac5a969a 100644 --- a/x-pack/test/functional/apps/discover/value_suggestions.ts +++ b/x-pack/test/functional/apps/discover/value_suggestions.ts @@ -36,10 +36,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.uiSettings.update({ 'doc_table:legacy': false, }); + await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings(); }); after(async () => { await kibanaServer.uiSettings.unset('doc_table:legacy'); + await PageObjects.common.unsetTime(); await kibanaServer.savedObjects.cleanStandardList(); }); From b323923e65af29416fc820fa4e7c8282d16f8ecc Mon Sep 17 00:00:00 2001 From: Garrett Spong Date: Wed, 12 Jul 2023 01:50:10 -0600 Subject: [PATCH 54/97] [Security Solution] [Elastic AI Assistant] Consolidates settings into a single modal (#160468) ## Summary This PR fixes the disjointed settings across the assistant by combining them all into a single settings modal. It also resolves the Connector `Model` configuration not being available when using the `OpenAI` variant of the GenAI Connector. Additional issues resolved: - [x] Clearing conversation doesn't restore default system prompt - [X] Double repeated welcome prompt - [X] Clicking skip button broken Resolves: https://github.com/elastic/security-team/issues/7110 Resolves: https://github.com/elastic/kibana/pull/161039#pullrequestreview-1517129764 Resolves: https://github.com/elastic/kibana/pull/161027#pullrequestreview-1523018176 #### Conversations

#### Quick Prompts

#### System Prompts

#### Anonymization

### Checklist Delete any items that are not applicable to this PR. - [X] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [X] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../impl/assistant/api.tsx | 3 +- .../assistant/assistant_overlay/index.tsx | 2 +- .../impl/assistant/constants.ts | 1 + .../conversation_settings_popover.tsx | 129 ------- .../conversation_selector/index.tsx | 41 +-- .../conversation_selector/translations.ts | 2 +- .../conversation_selector_settings/index.tsx | 251 ++++++++++++++ .../translations.ts | 57 ++++ .../conversation_settings.tsx | 265 +++++++++++++++ .../conversation_settings/helpers.tsx | 33 ++ .../conversation_settings/translations.ts | 43 +++ .../impl/assistant/helpers.ts | 27 ++ .../impl/assistant/index.test.tsx | 4 +- .../impl/assistant/index.tsx | 122 +++---- .../assistant/prompt_editor/index.test.tsx | 4 +- .../system_prompt/index.test.tsx | 33 +- .../prompt_editor/system_prompt/index.tsx | 32 +- .../select_system_prompt/index.test.tsx | 10 + .../select_system_prompt/index.tsx | 77 ++--- .../conversation_multi_selector.tsx | 13 +- .../system_prompt_modal.tsx | 272 --------------- .../system_prompt_selector.tsx | 8 +- .../system_prompt_selector/translations.ts | 2 +- .../system_prompt_settings.tsx | 264 +++++++++++++++ .../system_prompt_modal/translations.ts | 25 +- .../add_quick_prompt_modal.tsx | 229 ------------- .../prompt_context_selector.tsx | 6 +- .../quick_prompt_selector.tsx | 12 +- .../quick_prompt_selector/translations.ts | 2 +- .../quick_prompt_settings.tsx | 235 +++++++++++++ .../translations.ts | 32 +- .../assistant/quick_prompts/quick_prompts.tsx | 28 +- .../assistant/quick_prompts/translations.ts | 6 + .../advanced_settings/advanced_settings.tsx | 45 +++ .../advanced_settings/translations.ts | 21 ++ .../assistant/settings/assistant_settings.tsx | 315 ++++++++++++++++++ .../settings/assistant_settings_button.tsx | 74 ++++ .../impl/assistant/settings/translations.ts | 85 +++++ .../use_settings_updater.tsx | 108 ++++++ .../impl/assistant/streaming_text/index.tsx | 7 +- .../impl/assistant/translations.ts | 40 --- .../use_conversation/sample_conversations.tsx | 5 - .../impl/assistant_context/index.tsx | 21 +- .../impl/assistant_context/types.tsx | 1 + .../connectorland/connector_button/index.tsx | 10 +- .../connector_missing_callout/index.tsx | 58 ++++ .../connector_selector/index.tsx | 59 ++-- .../connectorland/connector_setup/index.tsx | 43 ++- .../models/model_selector/model_selector.tsx | 109 ++++++ .../models/model_selector/translations.ts | 35 ++ .../impl/connectorland/translations.ts | 14 + .../anonymization_settings/index.test.tsx | 73 +--- .../settings/anonymization_settings/index.tsx | 125 +++---- .../anonymization_settings/translations.ts | 13 +- .../index.test.tsx | 42 --- .../anonymization_settings_modal/index.tsx | 26 -- .../translations.ts | 29 -- .../settings/settings_popover/index.test.tsx | 39 --- .../settings/settings_popover/index.tsx | 90 ----- .../settings/settings_popover/translations.ts | 22 -- .../context_editor/index.tsx | 19 +- .../context_editor/toolbar/index.test.tsx | 1 + .../context_editor/toolbar/index.tsx | 24 ++ .../context_editor/translations.ts | 6 + .../content/prompts/system/translations.ts | 2 +- .../timeline/tabs_content/translations.ts | 9 +- 66 files changed, 2469 insertions(+), 1371 deletions(-) delete mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_settings_popover/conversation_settings_popover.tsx rename x-pack/packages/kbn-elastic-assistant/impl/assistant/{ => conversations}/conversation_selector/index.tsx (89%) rename x-pack/packages/kbn-elastic-assistant/impl/assistant/{ => conversations}/conversation_selector/translations.ts (97%) create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/index.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/translations.ts create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/conversation_settings.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/helpers.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/translations.ts delete mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_modal.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_settings.tsx delete mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/add_quick_prompt_modal/add_quick_prompt_modal.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_settings/quick_prompt_settings.tsx rename x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/{add_quick_prompt_modal => quick_prompt_settings}/translations.ts (54%) create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/advanced_settings/advanced_settings.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/advanced_settings/translations.ts create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/assistant_settings.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/assistant_settings_button.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/translations.ts create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_missing_callout/index.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/model_selector.tsx create mode 100644 x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/translations.ts delete mode 100644 x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/index.test.tsx delete mode 100644 x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/index.tsx delete mode 100644 x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/translations.ts delete mode 100644 x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/index.test.tsx delete mode 100644 x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/index.tsx delete mode 100644 x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/translations.ts diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx index 798da471e32d8..0bb68409caf91 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx @@ -11,6 +11,7 @@ import { HttpSetup } from '@kbn/core-http-browser'; import type { Message } from '../assistant_context/types'; import { Conversation } from '../assistant_context/types'; import { API_ERROR } from './translations'; +import { MODEL_GPT_3_5_TURBO } from '../connectorland/models/model_selector/model_selector'; export interface FetchConnectorExecuteAction { apiConfig: Conversation['apiConfig']; @@ -33,7 +34,7 @@ export const fetchConnectorExecuteAction = async ({ const body = apiConfig?.provider === OpenAiProviderType.OpenAi ? { - model: 'gpt-3.5-turbo', + model: apiConfig.model ?? MODEL_GPT_3_5_TURBO, messages: outboundMessages, n: 1, stop: null, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx index 32f0b48aa2a23..5a25c01468dee 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_overlay/index.tsx @@ -60,7 +60,7 @@ export const AssistantOverlay = React.memo(({ isAssistantEnabled }) => { const handleShortcutPress = useCallback(() => { // Try to restore the last conversation on shortcut pressed if (!isModalVisible) { - setConversationId(localStorageLastConversationId || WELCOME_CONVERSATION_TITLE); + setConversationId(localStorageLastConversationId ?? WELCOME_CONVERSATION_TITLE); } setIsModalVisible(!isModalVisible); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/constants.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/constants.ts index 7d4d7f97c207c..37ed0356cc697 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/constants.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/constants.ts @@ -11,6 +11,7 @@ export const TEST_IDS = { ADD_SYSTEM_PROMPT: 'addSystemPrompt', PROMPT_SUPERSELECT: 'promptSuperSelect', CONVERSATIONS_MULTISELECTOR_OPTION: (id: string) => `conversationMultiSelectorOption-${id}`, + SETTINGS_MODAL: 'settingsModal', SYSTEM_PROMPT_MODAL: { ID: 'systemPromptModal', PROMPT_TEXT: 'systemPromptModalPromptText', diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_settings_popover/conversation_settings_popover.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_settings_popover/conversation_settings_popover.tsx deleted file mode 100644 index 6c6c8c598f270..0000000000000 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_settings_popover/conversation_settings_popover.tsx +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EuiButtonIcon, - EuiFormRow, - EuiPopover, - EuiPopoverTitle, - EuiLink, - EuiToolTip, -} from '@elastic/eui'; -import React, { useCallback, useMemo, useRef, useState } from 'react'; - -import { ActionTypeRegistryContract } from '@kbn/triggers-actions-ui-plugin/public'; -import { HttpSetup } from '@kbn/core-http-browser'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { OpenAiProviderType } from '@kbn/stack-connectors-plugin/public/common'; -import { Conversation, Prompt } from '../../..'; -import * as i18n from '../translations'; -import { ConnectorSelector } from '../../connectorland/connector_selector'; -import { SelectSystemPrompt } from '../prompt_editor/system_prompt/select_system_prompt'; - -export interface ConversationSettingsPopoverProps { - actionTypeRegistry: ActionTypeRegistryContract; - conversation: Conversation; - http: HttpSetup; - isDisabled?: boolean; - allSystemPrompts: Prompt[]; -} - -export const ConversationSettingsPopover: React.FC = React.memo( - ({ actionTypeRegistry, conversation, http, isDisabled = false, allSystemPrompts }) => { - const [isSettingsOpen, setIsSettingsOpen] = useState(false); - // So we can hide the settings popover when the connector modal is displayed - const popoverPanelRef = useRef(null); - - const provider = useMemo(() => { - return conversation.apiConfig?.provider; - }, [conversation.apiConfig]); - - const selectedPrompt: Prompt | undefined = useMemo(() => { - const convoDefaultSystemPromptId = conversation?.apiConfig.defaultSystemPromptId; - if (convoDefaultSystemPromptId && allSystemPrompts) { - return allSystemPrompts.find((prompt) => prompt.id === convoDefaultSystemPromptId); - } - return allSystemPrompts.find((prompt) => prompt.isNewConversationDefault); - }, [conversation, allSystemPrompts]); - - const closeSettingsHandler = useCallback(() => { - setIsSettingsOpen(false); - }, []); - - // Hide settings panel when modal is visible (to keep visual clutter minimal) - const onDescendantModalVisibilityChange = useCallback((isVisible: boolean) => { - if (popoverPanelRef.current) { - popoverPanelRef.current.style.visibility = isVisible ? 'hidden' : 'visible'; - } - }, []); - - return ( - - setIsSettingsOpen(!isSettingsOpen)} - iconType="controlsVertical" - aria-label={i18n.SETTINGS_TITLE} - data-test-subj="assistant-settings-button" - /> - - } - isOpen={isSettingsOpen} - closePopover={closeSettingsHandler} - anchorPosition="rightCenter" - panelRef={(el) => (popoverPanelRef.current = el)} - > - {i18n.SETTINGS_TITLE} -
- - - - } - > - - - - {provider === OpenAiProviderType.OpenAi && <>} - - - - -
-
- ); - } -); -ConversationSettingsPopover.displayName = 'ConversationSettingsPopover'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_selector/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector/index.tsx similarity index 89% rename from x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_selector/index.tsx rename to x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector/index.tsx index 37d292152c496..77e0c703ea4e5 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_selector/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector/index.tsx @@ -20,20 +20,20 @@ import useEvent from 'react-use/lib/useEvent'; import { css } from '@emotion/react'; import { OpenAiProviderType } from '@kbn/stack-connectors-plugin/common/gen_ai/constants'; -import { Conversation } from '../../..'; -import { useAssistantContext } from '../../assistant_context'; +import { Conversation } from '../../../..'; +import { useAssistantContext } from '../../../assistant_context'; import * as i18n from './translations'; -import { DEFAULT_CONVERSATION_TITLE } from '../use_conversation/translations'; -import { useConversation } from '../use_conversation'; -import { SystemPromptSelectorOption } from '../prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector'; +import { DEFAULT_CONVERSATION_TITLE } from '../../use_conversation/translations'; +import { useConversation } from '../../use_conversation'; +import { SystemPromptSelectorOption } from '../../prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector'; const isMac = navigator.platform.toLowerCase().indexOf('mac') >= 0; interface Props { - conversationId?: string; defaultConnectorId?: string; defaultProvider?: OpenAiProviderType; - onSelectionChange?: (value: string) => void; + selectedConversationId: string | undefined; + setSelectedConversationId: React.Dispatch>; shouldDisableKeyboardShortcut?: () => boolean; isDisabled?: boolean; } @@ -56,17 +56,16 @@ export type ConversationSelectorOption = EuiComboBoxOptionOption<{ export const ConversationSelector: React.FC = React.memo( ({ - conversationId = DEFAULT_CONVERSATION_TITLE, + selectedConversationId = DEFAULT_CONVERSATION_TITLE, defaultConnectorId, defaultProvider, - onSelectionChange, + setSelectedConversationId, shouldDisableKeyboardShortcut = () => false, isDisabled = false, }) => { const { allSystemPrompts } = useAssistantContext(); const { deleteConversation, setConversation } = useConversation(); - const [selectedConversationId, setSelectedConversationId] = useState(conversationId); const { conversations } = useAssistantContext(); const conversationIds = useMemo(() => Object.keys(conversations), [conversations]); @@ -112,7 +111,13 @@ export const ConversationSelector: React.FC = React.memo( } setSelectedConversationId(searchValue); }, - [allSystemPrompts, defaultConnectorId, defaultProvider, setConversation] + [ + allSystemPrompts, + defaultConnectorId, + defaultProvider, + setConversation, + setSelectedConversationId, + ] ); // Callback for when user deletes a conversation @@ -124,32 +129,29 @@ export const ConversationSelector: React.FC = React.memo( setTimeout(() => { deleteConversation(cId); }, 0); - // onSystemPromptDeleted(cId); }, - [conversationIds, deleteConversation, selectedConversationId] + [conversationIds, deleteConversation, selectedConversationId, setSelectedConversationId] ); const onChange = useCallback( (newOptions: ConversationSelectorOption[]) => { if (newOptions.length === 0) { setSelectedOptions([]); - // handleSelectionChange([]); } else if (conversationOptions.findIndex((o) => o.label === newOptions?.[0].label) !== -1) { setSelectedConversationId(newOptions?.[0].label); } - // setSelectedConversationId(value ?? DEFAULT_CONVERSATION_TITLE); }, - [conversationOptions] + [conversationOptions, setSelectedConversationId] ); const onLeftArrowClick = useCallback(() => { const prevId = getPreviousConversationId(conversationIds, selectedConversationId); setSelectedConversationId(prevId); - }, [conversationIds, selectedConversationId]); + }, [conversationIds, selectedConversationId, setSelectedConversationId]); const onRightArrowClick = useCallback(() => { const nextId = getNextConversationId(conversationIds, selectedConversationId); setSelectedConversationId(nextId); - }, [conversationIds, selectedConversationId]); + }, [conversationIds, selectedConversationId, setSelectedConversationId]); // Register keyboard listener for quick conversation switching const onKeyDown = useCallback( @@ -186,9 +188,8 @@ export const ConversationSelector: React.FC = React.memo( useEvent('keydown', onKeyDown); useEffect(() => { - onSelectionChange?.(selectedConversationId); setSelectedOptions(conversationOptions.filter((c) => c.label === selectedConversationId)); - }, [conversationOptions, onSelectionChange, selectedConversationId]); + }, [conversationOptions, selectedConversationId]); const renderOption: ( option: ConversationSelectorOption, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_selector/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector/translations.ts similarity index 97% rename from x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_selector/translations.ts rename to x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector/translations.ts index 625c3e3605f65..fb93bed03c5bb 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversation_selector/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector/translations.ts @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; export const SELECTED_CONVERSATION_LABEL = i18n.translate( 'xpack.elasticAssistant.assistant.conversationSelector.defaultConversationTitle', { - defaultMessage: 'Selected conversation', + defaultMessage: 'Conversations', } ); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/index.tsx new file mode 100644 index 0000000000000..873f7dc7bb098 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/index.tsx @@ -0,0 +1,251 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiButtonIcon, + EuiComboBox, + EuiComboBoxOptionOption, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiHighlight, + EuiToolTip, +} from '@elastic/eui'; +import React, { useCallback, useMemo, useState } from 'react'; +import { css } from '@emotion/react'; + +import { OpenAiProviderType } from '@kbn/stack-connectors-plugin/common/gen_ai/constants'; +import { Conversation, Prompt } from '../../../..'; +import { UseAssistantContext } from '../../../assistant_context'; +import * as i18n from './translations'; +import { SystemPromptSelectorOption } from '../../prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector'; + +interface Props { + allSystemPrompts: Prompt[]; + conversations: UseAssistantContext['conversations']; + onConversationDeleted: (conversationId: string) => void; + onConversationSelectionChange: (conversation?: Conversation | string) => void; + selectedConversationId?: string; + defaultConnectorId?: string; + defaultProvider?: OpenAiProviderType; +} + +const getPreviousConversationId = (conversationIds: string[], selectedConversationId = '') => { + return conversationIds.indexOf(selectedConversationId) === 0 + ? conversationIds[conversationIds.length - 1] + : conversationIds[conversationIds.indexOf(selectedConversationId) - 1]; +}; + +const getNextConversationId = (conversationIds: string[], selectedConversationId = '') => { + return conversationIds.indexOf(selectedConversationId) + 1 >= conversationIds.length + ? conversationIds[0] + : conversationIds[conversationIds.indexOf(selectedConversationId) + 1]; +}; + +export type ConversationSelectorSettingsOption = EuiComboBoxOptionOption<{ + isDefault: boolean; +}>; + +/** + * A disconnected variant of the ConversationSelector component that allows for + * modifiable settings without persistence. Also changes some styling and removes + * the keyboard shortcuts. Could be merged w/ ConversationSelector if refactored + * as a connected wrapper. + */ +export const ConversationSelectorSettings: React.FC = React.memo( + ({ + allSystemPrompts, + conversations, + onConversationDeleted, + onConversationSelectionChange, + selectedConversationId, + defaultConnectorId, + defaultProvider, + }) => { + const conversationIds = useMemo(() => Object.keys(conversations), [conversations]); + + const [conversationOptions, setConversationOptions] = useState< + ConversationSelectorSettingsOption[] + >(() => { + return Object.values(conversations).map((conversation) => ({ + value: { isDefault: conversation.isDefault ?? false }, + label: conversation.id, + })); + }); + + const selectedOptions = useMemo(() => { + return selectedConversationId + ? conversationOptions.filter((c) => c.label === selectedConversationId) ?? [] + : []; + }, [conversationOptions, selectedConversationId]); + + const handleSelectionChange = useCallback( + (conversationSelectorSettingsOption: ConversationSelectorSettingsOption[]) => { + const newConversation = + conversationSelectorSettingsOption.length === 0 + ? undefined + : Object.values(conversations).find( + (conversation) => conversation.id === conversationSelectorSettingsOption[0]?.label + ) ?? conversationSelectorSettingsOption[0]?.label; + onConversationSelectionChange(newConversation); + }, + [onConversationSelectionChange, conversations] + ); + + // Callback for when user types to create a new conversation + const onCreateOption = useCallback( + (searchValue, flattenedOptions = []) => { + if (!searchValue || !searchValue.trim().toLowerCase()) { + return; + } + + const normalizedSearchValue = searchValue.trim().toLowerCase(); + const optionExists = + flattenedOptions.findIndex( + (option: SystemPromptSelectorOption) => + option.label.trim().toLowerCase() === normalizedSearchValue + ) !== -1; + + const newOption = { + value: searchValue, + label: searchValue, + }; + + if (!optionExists) { + setConversationOptions([...conversationOptions, newOption]); + } + handleSelectionChange([newOption]); + }, + [conversationOptions, handleSelectionChange] + ); + + // Callback for when a user selects a conversation + const onChange = useCallback( + (newOptions: ConversationSelectorSettingsOption[]) => { + if (newOptions.length === 0) { + handleSelectionChange([]); + } else if (conversationOptions.findIndex((o) => o.label === newOptions?.[0].label) !== -1) { + handleSelectionChange(newOptions); + } + }, + [conversationOptions, handleSelectionChange] + ); + + // Callback for when user deletes a conversation + const onDelete = useCallback( + (label: string) => { + setConversationOptions(conversationOptions.filter((o) => o.label !== label)); + if (selectedOptions?.[0]?.label === label) { + handleSelectionChange([]); + } + onConversationDeleted(label); + }, + [conversationOptions, handleSelectionChange, onConversationDeleted, selectedOptions] + ); + + const onLeftArrowClick = useCallback(() => { + const prevId = getPreviousConversationId(conversationIds, selectedConversationId); + const previousOption = conversationOptions.filter((c) => c.label === prevId); + handleSelectionChange(previousOption); + }, [conversationIds, conversationOptions, handleSelectionChange, selectedConversationId]); + const onRightArrowClick = useCallback(() => { + const nextId = getNextConversationId(conversationIds, selectedConversationId); + const nextOption = conversationOptions.filter((c) => c.label === nextId); + handleSelectionChange(nextOption); + }, [conversationIds, conversationOptions, handleSelectionChange, selectedConversationId]); + + const renderOption: ( + option: ConversationSelectorSettingsOption, + searchValue: string, + OPTION_CONTENT_CLASSNAME: string + ) => React.ReactNode = (option, searchValue, contentClassName) => { + const { label, value } = option; + return ( + + + + {label} + + + {!value?.isDefault && ( + + + { + e.stopPropagation(); + onDelete(label); + }} + css={css` + visibility: hidden; + .parentFlexGroup:hover & { + visibility: visible; + } + `} + /> + + + )} + + ); + }; + + return ( + + + } + append={ + + } + /> + + ); + } +); + +ConversationSelectorSettings.displayName = 'ConversationSelectorSettings'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/translations.ts new file mode 100644 index 0000000000000..7ba634ded5f12 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/translations.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const SELECTED_CONVERSATION_LABEL = i18n.translate( + 'xpack.elasticAssistant.assistant.conversationSelectorSettings.defaultConversationTitle', + { + defaultMessage: 'Conversations', + } +); + +export const CONVERSATION_SELECTOR_ARIA_LABEL = i18n.translate( + 'xpack.elasticAssistant.assistant.conversationSelectorSettings.ariaLabel', + { + defaultMessage: 'Conversation selector', + } +); + +export const CONVERSATION_SELECTOR_PLACE_HOLDER = i18n.translate( + 'xpack.elasticAssistant.assistant.conversationSelectorSettings.placeholderTitle', + { + defaultMessage: 'Select or type to create new...', + } +); + +export const CONVERSATION_SELECTOR_CUSTOM_OPTION_TEXT = i18n.translate( + 'xpack.elasticAssistant.assistant.conversationSelectorSettings.CustomOptionTextTitle', + { + defaultMessage: 'Create new conversation:', + } +); + +export const PREVIOUS_CONVERSATION_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.conversationSelectorSettings.previousConversationTitle', + { + defaultMessage: 'Previous conversation', + } +); + +export const NEXT_CONVERSATION_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.conversationSelectorSettings.nextConversationTitle', + { + defaultMessage: 'Next conversation', + } +); + +export const DELETE_CONVERSATION = i18n.translate( + 'xpack.elasticAssistant.assistant.conversationSelectorSettings.deleteConversationTitle', + { + defaultMessage: 'Delete conversation', + } +); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/conversation_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/conversation_settings.tsx new file mode 100644 index 0000000000000..b519aeb9eb9ba --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/conversation_settings.tsx @@ -0,0 +1,265 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFormRow, EuiLink, EuiTitle, EuiText, EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; +import React, { useCallback, useMemo } from 'react'; + +import { ActionTypeRegistryContract } from '@kbn/triggers-actions-ui-plugin/public'; +import { HttpSetup } from '@kbn/core-http-browser'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { OpenAiProviderType } from '@kbn/stack-connectors-plugin/public/common'; +import { Conversation, Prompt } from '../../../..'; +import * as i18n from './translations'; +import * as i18nModel from '../../../connectorland/models/model_selector/translations'; + +import { ConnectorSelector } from '../../../connectorland/connector_selector'; +import { SelectSystemPrompt } from '../../prompt_editor/system_prompt/select_system_prompt'; +import { ModelSelector } from '../../../connectorland/models/model_selector/model_selector'; +import { UseAssistantContext } from '../../../assistant_context'; +import { ConversationSelectorSettings } from '../conversation_selector_settings'; +import { getDefaultSystemPromptFromConversation } from './helpers'; + +export interface ConversationSettingsProps { + actionTypeRegistry: ActionTypeRegistryContract; + allSystemPrompts: Prompt[]; + conversationSettings: UseAssistantContext['conversations']; + http: HttpSetup; + onSelectedConversationChange: (conversation?: Conversation) => void; + selectedConversation: Conversation | undefined; + setUpdatedConversationSettings: React.Dispatch< + React.SetStateAction + >; + isDisabled?: boolean; +} + +/** + * Settings for adding/removing conversation and configuring default system prompt and connector. + */ +export const ConversationSettings: React.FC = React.memo( + ({ + actionTypeRegistry, + allSystemPrompts, + selectedConversation, + onSelectedConversationChange, + conversationSettings, + http, + setUpdatedConversationSettings, + isDisabled = false, + }) => { + // Defaults + const defaultSystemPrompt = useMemo(() => { + return ( + allSystemPrompts.find((systemPrompt) => systemPrompt.isNewConversationDefault) ?? + allSystemPrompts[0] + ); + }, [allSystemPrompts]); + + // Conversation callbacks + // When top level conversation selection changes + const onConversationSelectionChange = useCallback( + (c?: Conversation | string) => { + const isNew = typeof c === 'string'; + const newSelectedConversation: Conversation | undefined = isNew + ? { + id: c ?? '', + messages: [], + apiConfig: { + connectorId: undefined, + provider: undefined, + defaultSystemPromptId: defaultSystemPrompt?.id, + }, + } + : c; + + if (newSelectedConversation != null) { + setUpdatedConversationSettings((prev) => { + return { + ...prev, + [newSelectedConversation.id]: newSelectedConversation, + }; + }); + } + + onSelectedConversationChange(newSelectedConversation); + }, + [defaultSystemPrompt?.id, onSelectedConversationChange, setUpdatedConversationSettings] + ); + + const onConversationDeleted = useCallback( + (conversationId: string) => { + setUpdatedConversationSettings((prev) => { + const { [conversationId]: prevConversation, ...updatedConversations } = prev; + if (prevConversation != null) { + return updatedConversations; + } + return prev; + }); + }, + [setUpdatedConversationSettings] + ); + + const selectedSystemPrompt = useMemo( + () => + getDefaultSystemPromptFromConversation({ + allSystemPrompts, + conversation: selectedConversation, + defaultSystemPrompt, + }), + [allSystemPrompts, defaultSystemPrompt, selectedConversation] + ); + + const handleOnSystemPromptSelectionChange = useCallback( + (systemPromptId?: string) => { + if (selectedConversation != null) { + setUpdatedConversationSettings((prev) => ({ + ...prev, + [selectedConversation.id]: { + ...selectedConversation, + apiConfig: { + ...selectedConversation.apiConfig, + defaultSystemPromptId: systemPromptId, + }, + }, + })); + } + }, + [selectedConversation, setUpdatedConversationSettings] + ); + + const selectedConnectorId = useMemo( + () => selectedConversation?.apiConfig.connectorId, + [selectedConversation?.apiConfig.connectorId] + ); + + const selectedProvider = useMemo( + () => selectedConversation?.apiConfig.provider, + [selectedConversation?.apiConfig.provider] + ); + + const handleOnConnectorSelectionChange = useCallback( + (connectorId: string, provider: OpenAiProviderType) => { + if (selectedConversation != null) { + setUpdatedConversationSettings((prev) => ({ + ...prev, + [selectedConversation.id]: { + ...selectedConversation, + apiConfig: { + ...selectedConversation.apiConfig, + connectorId, + provider, + }, + }, + })); + } + }, + [selectedConversation, setUpdatedConversationSettings] + ); + + const selectedModel = useMemo( + () => selectedConversation?.apiConfig.model, + [selectedConversation?.apiConfig.model] + ); + + const handleOnModelSelectionChange = useCallback( + (model?: string) => { + if (selectedConversation != null) { + setUpdatedConversationSettings((prev) => ({ + ...prev, + [selectedConversation.id]: { + ...selectedConversation, + apiConfig: { + ...selectedConversation.apiConfig, + model, + }, + }, + })); + } + }, + [selectedConversation, setUpdatedConversationSettings] + ); + + return ( + <> + +

{i18n.SETTINGS_TITLE}

+
+ + {i18n.SETTINGS_DESCRIPTION} + + + + + + + + + + + + } + > + {}} + onConnectorSelectionChange={handleOnConnectorSelectionChange} + selectedConnectorId={selectedConnectorId} + /> + + + {selectedProvider === OpenAiProviderType.OpenAi && ( + + + + )} + + ); + } +); +ConversationSettings.displayName = 'ConversationSettings'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/helpers.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/helpers.tsx new file mode 100644 index 0000000000000..5d0cc04aa9630 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/helpers.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Conversation, Prompt } from '../../../..'; + +/** + * Returns a conversation's default system prompt, or the default system prompt if the conversation does not have one. + * @param allSystemPrompts + * @param conversation + * @param defaultSystemPrompt + */ +export const getDefaultSystemPromptFromConversation = ({ + allSystemPrompts, + conversation, + defaultSystemPrompt, +}: { + conversation: Conversation | undefined; + allSystemPrompts: Prompt[]; + defaultSystemPrompt: Prompt; +}) => { + const convoDefaultSystemPromptId = conversation?.apiConfig.defaultSystemPromptId; + if (convoDefaultSystemPromptId && allSystemPrompts) { + return ( + allSystemPrompts.find((prompt) => prompt.id === convoDefaultSystemPromptId) ?? + defaultSystemPrompt + ); + } + return allSystemPrompts.find((prompt) => prompt.isNewConversationDefault) ?? defaultSystemPrompt; +}; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/translations.ts new file mode 100644 index 0000000000000..ede5fd879664f --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/translations.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const SETTINGS_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.conversations.settings.settingsTitle', + { + defaultMessage: 'Conversations', + } +); + +export const SETTINGS_DESCRIPTION = i18n.translate( + 'xpack.elasticAssistant.assistant.conversations.settings.settingsDescription', + { + defaultMessage: 'Create and manage conversations with the Elastic AI Assistant', + } +); + +export const CONNECTOR_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.conversations.settings.connectorTitle', + { + defaultMessage: 'Connector', + } +); + +export const SETTINGS_PROMPT_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.conversations.settings.promptTitle', + { + defaultMessage: 'System Prompt', + } +); + +export const SETTINGS_PROMPT_HELP_TEXT_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.conversations.settings.promptHelpTextTitle', + { + defaultMessage: 'Context provided as part of every conversation', + } +); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts index 8cf7986600041..4f671b4c9758c 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts @@ -5,7 +5,10 @@ * 2.0. */ +import { BASE_CONVERSATIONS, Conversation } from '../..'; import type { Message } from '../assistant_context/types'; +import { WELCOME_CONVERSATION_TITLE } from './use_conversation/translations'; +import { enterpriseMessaging } from './use_conversation/sample_conversations'; export const getMessageFromRawResponse = (rawResponse: string): Message => { const dateTimeString = new Date().toLocaleString(); // TODO: Pull from response @@ -23,3 +26,27 @@ export const getMessageFromRawResponse = (rawResponse: string): Message => { }; } }; + +export const getWelcomeConversation = (isAssistantEnabled: boolean): Conversation => { + const conversation = BASE_CONVERSATIONS[WELCOME_CONVERSATION_TITLE]; + const doesConversationHaveMessages = conversation.messages.length > 0; + + if (!isAssistantEnabled) { + if ( + !doesConversationHaveMessages || + conversation.messages[conversation.messages.length - 1].content !== + enterpriseMessaging[0].content + ) { + return { + ...conversation, + messages: [...conversation.messages, ...enterpriseMessaging], + }; + } + return conversation; + } + + return { + ...conversation, + messages: BASE_CONVERSATIONS[WELCOME_CONVERSATION_TITLE].messages, + }; +}; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.test.tsx index 44f50e26c1115..adbdc0df86006 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.test.tsx @@ -146,7 +146,7 @@ describe('Assistant', () => { }); describe('when no connectors are loaded', () => { - it('should clear conversation id in local storage', async () => { + it('should set welcome conversation id in local storage', async () => { const emptyConnectors: unknown[] = []; jest.mocked(useLoadConnectors).mockReturnValue({ @@ -157,7 +157,7 @@ describe('Assistant', () => { renderAssistant(); expect(persistToLocalStorage).toHaveBeenCalled(); - expect(persistToLocalStorage).toHaveBeenLastCalledWith(''); + expect(persistToLocalStorage).toHaveBeenLastCalledWith(WELCOME_CONVERSATION_TITLE); }); }); }); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx index 58e084db643af..a9ce41747aa17 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/index.tsx @@ -16,7 +16,6 @@ import { EuiToolTip, EuiSwitchEvent, EuiSwitch, - EuiCallOut, EuiModalFooter, EuiModalHeader, EuiModalBody, @@ -29,20 +28,18 @@ import { OpenAiProviderType } from '@kbn/stack-connectors-plugin/common/gen_ai/c import { ActionConnectorProps } from '@kbn/triggers-actions-ui-plugin/public/types'; import { AssistantTitle } from './assistant_title'; import { UpgradeButtons } from '../upgrade/upgrade_buttons'; -import { getMessageFromRawResponse } from './helpers'; +import { getMessageFromRawResponse, getWelcomeConversation } from './helpers'; -import { ConversationSettingsPopover } from './conversation_settings_popover/conversation_settings_popover'; import { useAssistantContext } from '../assistant_context'; import { ContextPills } from './context_pills'; import { getNewSelectedPromptContext } from '../data_anonymization/get_new_selected_prompt_context'; -import { SettingsPopover } from '../data_anonymization/settings/settings_popover'; import { PromptTextArea } from './prompt_textarea'; import type { PromptContext, SelectedPromptContext } from './prompt_context/types'; import { useConversation } from './use_conversation'; import { CodeBlockDetails } from './use_conversation/helpers'; import { useSendMessages } from './use_send_messages'; import type { Message } from '../assistant_context/types'; -import { ConversationSelector } from './conversation_selector'; +import { ConversationSelector } from './conversations/conversation_selector'; import { PromptEditor } from './prompt_editor'; import { getCombinedMessage } from './prompt/helpers'; import * as i18n from './translations'; @@ -50,7 +47,8 @@ import { QuickPrompts } from './quick_prompts/quick_prompts'; import { useLoadConnectors } from '../connectorland/use_load_connectors'; import { useConnectorSetup } from '../connectorland/connector_setup'; import { WELCOME_CONVERSATION_TITLE } from './use_conversation/translations'; -import { BASE_CONVERSATIONS, enterpriseMessaging } from './use_conversation/sample_conversations'; +import { AssistantSettingsButton } from './settings/assistant_settings_button'; +import { ConnectorMissingCallout } from '../connectorland/connector_missing_callout'; export interface Props { conversationId?: string; @@ -97,46 +95,7 @@ const AssistantComponent: React.FC = ({ useConversation(); const { isLoading, sendMessages } = useSendMessages(); - const [selectedConversationId, setSelectedConversationId] = useState(conversationId); - const currentConversation = useMemo( - () => conversations[selectedConversationId] ?? createConversation({ conversationId }), - [conversationId, conversations, createConversation, selectedConversationId] - ); - - // Welcome conversation is a special 'setup' case when no connector exists, mostly extracted to `ConnectorSetup` component, - // but currently a bit of state is littered throughout the assistant component. TODO: clean up/isolate this state - const welcomeConversation = useMemo(() => { - const conversation = - conversations[selectedConversationId] ?? BASE_CONVERSATIONS[WELCOME_CONVERSATION_TITLE]; - const doesConversationHaveMessages = conversation.messages.length > 0; - if (!isAssistantEnabled) { - if ( - !doesConversationHaveMessages || - conversation.messages[conversation.messages.length - 1].content !== - enterpriseMessaging[0].content - ) { - return { - ...conversation, - messages: [...conversation.messages, ...enterpriseMessaging], - }; - } - return conversation; - } - - return doesConversationHaveMessages - ? { - ...conversation, - messages: [ - ...conversation.messages, - ...BASE_CONVERSATIONS[WELCOME_CONVERSATION_TITLE].messages, - ], - } - : { - ...conversation, - messages: BASE_CONVERSATIONS[WELCOME_CONVERSATION_TITLE].messages, - }; - }, [conversations, isAssistantEnabled, selectedConversationId]); - + // Connector details const { data: connectors, isSuccess: areConnectorsFetched, @@ -150,11 +109,30 @@ const AssistantComponent: React.FC = ({ [connectors] ); + // Welcome setup state + const isWelcomeSetup = useMemo(() => (connectors?.length ?? 0) === 0, [connectors?.length]); + const isDisabled = isWelcomeSetup || !isAssistantEnabled; + + // Welcome conversation is a special 'setup' case when no connector exists, mostly extracted to `ConnectorSetup` component, + // but currently a bit of state is littered throughout the assistant component. TODO: clean up/isolate this state + const welcomeConversation = useMemo( + () => getWelcomeConversation(isAssistantEnabled), + [isAssistantEnabled] + ); + + const [selectedConversationId, setSelectedConversationId] = useState( + isWelcomeSetup ? welcomeConversation.id : conversationId + ); + const currentConversation = useMemo( + () => conversations[selectedConversationId] ?? createConversation({ conversationId }), + [conversationId, conversations, createConversation, selectedConversationId] + ); + // Remember last selection for reuse after keyboard shortcut is pressed. // Clear it if there is no connectors useEffect(() => { if (areConnectorsFetched && !connectors?.length) { - return setLastConversationId(''); + return setLastConversationId(WELCOME_CONVERSATION_TITLE); } if (!currentConversation.excludeFromLastConversationStorage) { @@ -162,9 +140,6 @@ const AssistantComponent: React.FC = ({ } }, [areConnectorsFetched, connectors?.length, currentConversation, setLastConversationId]); - const isWelcomeSetup = (connectors?.length ?? 0) === 0; - const isDisabled = isWelcomeSetup || !isAssistantEnabled; - const { comments: connectorComments, prompt: connectorPrompt } = useConnectorSetup({ actionTypeRegistry, http, @@ -479,10 +454,10 @@ const AssistantComponent: React.FC = ({ `} > setSelectedConversationId(id)} + selectedConversationId={selectedConversationId} + setSelectedConversationId={setSelectedConversationId} shouldDisableKeyboardShortcut={shouldDisableConversationSelectorHotkeys} isDisabled={isDisabled} /> @@ -511,26 +486,17 @@ const AssistantComponent: React.FC = ({
- + - {!isWelcomeSetup && showMissingConnectorCallout && ( - <> - -

{i18n.MISSING_CONNECTOR_CALLOUT_DESCRIPTION}

-
- - - )} )} @@ -550,7 +516,20 @@ const AssistantComponent: React.FC = ({ )} - {comments} + + {comments} + + {!isWelcomeSetup && showMissingConnectorCallout && ( + <> + + + + + + + + )} + = ({ /> - - - diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/index.test.tsx index b14e69160f9c3..b671d225bac4f 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/index.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/index.test.tsx @@ -42,7 +42,7 @@ const defaultProps: Props = { describe('PromptEditorComponent', () => { beforeEach(() => jest.clearAllMocks()); - it('renders the system prompt selector when isNewConversation is true', async () => { + it('renders the system prompt viewer when isNewConversation is true', async () => { render( @@ -50,7 +50,7 @@ describe('PromptEditorComponent', () => { ); await waitFor(() => { - expect(screen.getByTestId('selectSystemPrompt')).toBeInTheDocument(); + expect(screen.getByTestId('systemPromptText')).toBeInTheDocument(); }); }); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/index.test.tsx index c46116b88557d..cb2e3870702f1 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/index.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/index.test.tsx @@ -71,27 +71,27 @@ describe('SystemPrompt', () => { }); }); - describe('when conversation is undefined', () => { + describe('when conversation is undefined and default prompt is used', () => { const conversation = undefined; beforeEach(() => { render(); }); - it('renders the system prompt select', () => { - expect(screen.getByTestId('selectSystemPrompt')).toBeInTheDocument(); + it('does render the system prompt fallback text', () => { + expect(screen.getByTestId('systemPromptText')).toBeInTheDocument(); }); - it('does NOT render the system prompt text', () => { - expect(screen.queryByTestId('systemPromptText')).not.toBeInTheDocument(); + it('does NOT render the system prompt select', () => { + expect(screen.queryByTestId('selectSystemPrompt')).not.toBeInTheDocument(); }); - it('does NOT render the edit button', () => { - expect(screen.queryByTestId('edit')).not.toBeInTheDocument(); + it('does render the edit button', () => { + expect(screen.getByTestId('edit')).toBeInTheDocument(); }); - it('does NOT render the clear button', () => { - expect(screen.queryByTestId('clear')).not.toBeInTheDocument(); + it('does render the clear button', () => { + expect(screen.getByTestId('clear')).toBeInTheDocument(); }); }); @@ -117,7 +117,8 @@ describe('SystemPrompt', () => { }); }); - describe('when a new prompt is saved', () => { + // TODO: To be implemented as part of the global settings tests instead of within the SystemPrompt component + describe.skip('when a new prompt is saved', () => { it('should save new prompt correctly', async () => { const customPromptName = 'custom prompt'; const customPromptText = 'custom prompt text'; @@ -420,18 +421,6 @@ describe('SystemPrompt', () => { expect(screen.getByTestId('selectSystemPrompt')).toBeInTheDocument(); }); - it('clears the selected system prompt when the clear button is clicked', () => { - const apiConfig = { - apiConfig: { defaultSystemPromptId: undefined }, - conversationId: 'Default', - }; - render(); - - userEvent.click(screen.getByTestId('clear')); - - expect(mockUseConversation.setApiConfig).toHaveBeenCalledWith(apiConfig); - }); - it('shows the system prompt select when system prompt text is clicked', () => { render( diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/index.tsx index fd08b418605e1..8520f8da55c26 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/index.tsx @@ -6,14 +6,13 @@ */ import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip } from '@elastic/eui'; -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { css } from '@emotion/react'; import { useAssistantContext } from '../../../assistant_context'; -import { Conversation } from '../../../..'; +import { Conversation, Prompt } from '../../../..'; import * as i18n from './translations'; import { SelectSystemPrompt } from './select_system_prompt'; -import { useConversation } from '../../use_conversation'; interface Props { conversation: Conversation | undefined; @@ -21,26 +20,24 @@ interface Props { const SystemPromptComponent: React.FC = ({ conversation }) => { const { allSystemPrompts } = useAssistantContext(); - const { setApiConfig } = useConversation(); - const selectedPrompt = useMemo( - () => allSystemPrompts?.find((p) => p.id === conversation?.apiConfig.defaultSystemPromptId), - [allSystemPrompts, conversation] + const [selectedPrompt, setSelectedPrompt] = useState( + allSystemPrompts?.find((p) => p.id === conversation?.apiConfig.defaultSystemPromptId) ?? + allSystemPrompts?.[0] ); + useEffect(() => { + setSelectedPrompt( + allSystemPrompts?.find((p) => p.id === conversation?.apiConfig.defaultSystemPromptId) ?? + allSystemPrompts?.[0] + ); + }, [allSystemPrompts, conversation]); + const [isEditing, setIsEditing] = React.useState(false); const handleClearSystemPrompt = useCallback(() => { - if (conversation) { - setApiConfig({ - conversationId: conversation.id, - apiConfig: { - ...conversation.apiConfig, - defaultSystemPromptId: undefined, - }, - }); - } - }, [conversation, setApiConfig]); + setSelectedPrompt(undefined); + }, []); const handleEditSystemPrompt = useCallback(() => setIsEditing(true), []); @@ -48,6 +45,7 @@ const SystemPromptComponent: React.FC = ({ conversation }) => {
{selectedPrompt == null || isEditing ? ( void; - fullWidth?: boolean; isClearable?: boolean; isEditing?: boolean; + isDisabled?: boolean; isOpen?: boolean; - onSystemPromptModalVisibilityChange?: (isVisible: boolean) => void; setIsEditing?: React.Dispatch>; showTitles?: boolean; + onSystemPromptSelectionChange?: (promptId: string) => void; } const ADD_NEW_SYSTEM_PROMPT = 'ADD_NEW_SYSTEM_PROMPT'; const SelectSystemPromptComponent: React.FC = ({ + allSystemPrompts, + compressed = false, conversation, selectedPrompt, clearSelectedSystemPrompt, - fullWidth = true, isClearable = false, isEditing = false, + isDisabled = false, isOpen = false, - onSystemPromptModalVisibilityChange, + onSystemPromptSelectionChange, setIsEditing, showTitles = false, }) => { - const { allSystemPrompts, setAllSystemPrompts, conversations, setConversations } = + const { isSettingsModalVisible, setIsSettingsModalVisible, setSelectedSettingsTab } = useAssistantContext(); - const { setApiConfig } = useConversation(); const [isOpenLocal, setIsOpenLocal] = useState(isOpen); @@ -78,8 +81,6 @@ const SelectSystemPromptComponent: React.FC = ({ [conversation, setApiConfig] ); - // Connector Modal State - const [isSystemPromptModalVisible, setIsSystemPromptModalVisible] = useState(false); const addNewSystemPrompt = useMemo(() => { return { value: ADD_NEW_SYSTEM_PROMPT, @@ -100,29 +101,6 @@ const SelectSystemPromptComponent: React.FC = ({ }; }, []); - // Callback for modal onSave, saves to local storage on change - const onSystemPromptsChange = useCallback( - (newSystemPrompts: Prompt[], updatedConversations?: Conversation[]) => { - setAllSystemPrompts(newSystemPrompts); - setIsSystemPromptModalVisible(false); - onSystemPromptModalVisibilityChange?.(false); - - if (updatedConversations && updatedConversations.length > 0) { - const updatedConversationObject = updatedConversations?.reduce< - Record - >((updatedObj, currentConv) => { - updatedObj[currentConv.id] = currentConv; - return updatedObj; - }, {}); - setConversations({ - ...conversations, - ...updatedConversationObject, - }); - } - }, - [onSystemPromptModalVisibilityChange, setAllSystemPrompts, conversations, setConversations] - ); - // SuperSelect State/Actions const options = useMemo( () => getOptions({ prompts: allSystemPrompts, showTitles }), @@ -132,14 +110,26 @@ const SelectSystemPromptComponent: React.FC = ({ const onChange = useCallback( (selectedSystemPromptId) => { if (selectedSystemPromptId === ADD_NEW_SYSTEM_PROMPT) { - onSystemPromptModalVisibilityChange?.(true); - setIsSystemPromptModalVisible(true); + setIsSettingsModalVisible(true); + setSelectedSettingsTab(SYSTEM_PROMPTS_TAB); return; } - setSelectedSystemPrompt(allSystemPrompts.find((sp) => sp.id === selectedSystemPromptId)); + // Note: if callback is provided, this component does not persist. Extract to separate component + if (onSystemPromptSelectionChange != null) { + onSystemPromptSelectionChange(selectedSystemPromptId); + } else { + setSelectedSystemPrompt(allSystemPrompts.find((sp) => sp.id === selectedSystemPromptId)); + } setIsEditing?.(false); }, - [allSystemPrompts, onSystemPromptModalVisibilityChange, setIsEditing, setSelectedSystemPrompt] + [ + allSystemPrompts, + onSystemPromptSelectionChange, + setIsEditing, + setIsSettingsModalVisible, + setSelectedSettingsTab, + setSelectedSystemPrompt, + ] ); const clearSystemPrompt = useCallback(() => { @@ -170,16 +160,18 @@ const SelectSystemPromptComponent: React.FC = ({ // Limits popover z-index to prevent it from getting too high and covering tooltips. // If the z-index is not defined, when a popover is opened, it sets the target z-index + 2000 popoverProps={{ zIndex: euiThemeVars.euiZLevel8 }} + compressed={compressed} data-test-subj={TEST_IDS.PROMPT_SUPERSELECT} - fullWidth={fullWidth} + fullWidth hasDividers itemLayoutAlign="top" - isOpen={isOpenLocal && !isSystemPromptModalVisible} + disabled={isDisabled} + isOpen={isOpenLocal && !isSettingsModalVisible} onChange={onChange} onBlur={handleOnBlur} options={[...options, addNewSystemPrompt]} placeholder={i18n.SELECT_A_SYSTEM_PROMPT} - valueOfSelected={selectedPrompt?.id} + valueOfSelected={selectedPrompt?.id ?? allSystemPrompts[0].id} /> )} @@ -207,13 +199,6 @@ const SelectSystemPromptComponent: React.FC = ({ )} - {isSystemPromptModalVisible && ( - setIsSystemPromptModalVisible(false)} - onSystemPromptsChange={onSystemPromptsChange} - systemPrompts={allSystemPrompts} - /> - )} ); }; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/conversation_multi_selector/conversation_multi_selector.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/conversation_multi_selector/conversation_multi_selector.tsx index ea6cb525180b9..d53d3cc15e9e2 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/conversation_multi_selector/conversation_multi_selector.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/conversation_multi_selector/conversation_multi_selector.tsx @@ -13,6 +13,7 @@ import { Conversation } from '../../../../../..'; import * as i18n from '../translations'; interface Props { + isDisabled?: boolean; onConversationSelectionChange: (currentPromptConversations: Conversation[]) => void; conversations: Conversation[]; selectedConversations?: Conversation[]; @@ -22,7 +23,12 @@ interface Props { * Selector for choosing multiple Conversations */ export const ConversationMultiSelector: React.FC = React.memo( - ({ onConversationSelectionChange, conversations, selectedConversations = [] }) => { + ({ + conversations, + isDisabled = false, + onConversationSelectionChange, + selectedConversations = [], + }) => { // ComboBox options const options = useMemo( () => @@ -64,8 +70,11 @@ export const ConversationMultiSelector: React.FC = React.memo( return ( | React.MouseEvent - ) => void; - onSystemPromptsChange: (systemPrompts: Prompt[], newConversation?: Conversation[]) => void; -} - -/** - * Modal for adding/removing system prompts. Configure name, prompt and default conversations. - */ -export const SystemPromptModal: React.FC = React.memo( - ({ systemPrompts, onClose, onSystemPromptsChange }) => { - const { conversations } = useAssistantContext(); - // Local state for quick prompts (returned to parent on save via onSystemPromptsChange()) - const [updatedSystemPrompts, setUpdatedSystemPrompts] = useState(systemPrompts); - - // Form options - const [selectedSystemPrompt, setSelectedSystemPrompt] = useState(); - // Prompt - const [prompt, setPrompt] = useState(''); - const handlePromptTextChange = useCallback((e: React.ChangeEvent) => { - setPrompt(e.target.value); - }, []); - // Conversations this system prompt should be a default for - const [selectedConversations, setSelectedConversations] = useState([]); - - const onConversationSelectionChange = useCallback( - (currentPromptConversations: Conversation[]) => { - setSelectedConversations(currentPromptConversations); - }, - [] - ); - - /* - * updatedConversationWithPrompts calculates the present of prompt for - * each conversation. Based on the values of selected conversation, it goes - * through each conversation adds/removed the selected prompt on each conversation. - * - * */ - const getUpdatedConversationWithPrompts = useCallback(() => { - const currentPromptConversationIds = selectedConversations.map((convo) => convo.id); - - const allConversations = Object.values(conversations).map((convo) => ({ - ...convo, - apiConfig: { - ...convo.apiConfig, - defaultSystemPromptId: currentPromptConversationIds.includes(convo.id) - ? selectedSystemPrompt?.id - : convo.apiConfig.defaultSystemPromptId === selectedSystemPrompt?.id - ? // remove the the default System Prompt if it is assigned to a conversation - // but that conversation is not in the currentPromptConversationList - // This means conversation was removed in the current transaction - undefined - : // leave it as it is .. if that conversation was neither added nor removed. - convo.apiConfig.defaultSystemPromptId, - }, - })); - - return allConversations; - }, [selectedSystemPrompt, conversations, selectedConversations]); - // Whether this system prompt should be the default for new conversations - const [isNewConversationDefault, setIsNewConversationDefault] = useState(false); - const handleNewConversationDefaultChange = useCallback( - (e) => { - const isChecked = e.target.checked; - setIsNewConversationDefault(isChecked); - if (selectedSystemPrompt != null) { - setUpdatedSystemPrompts((prev) => { - return prev.map((pp) => { - return { - ...pp, - isNewConversationDefault: selectedSystemPrompt.id === pp.id && isChecked, - }; - }); - }); - setSelectedSystemPrompt((prev) => - prev != null ? { ...prev, isNewConversationDefault: isChecked } : prev - ); - } - }, - [selectedSystemPrompt] - ); - - // When top level system prompt selection changes - const onSystemPromptSelectionChange = useCallback( - (systemPrompt?: Prompt | string) => { - const newPrompt: Prompt | undefined = - typeof systemPrompt === 'string' - ? { - id: systemPrompt ?? '', - content: '', - name: systemPrompt ?? '', - promptType: 'system', - } - : systemPrompt; - - setSelectedSystemPrompt(newPrompt); - setPrompt(newPrompt?.content ?? ''); - setIsNewConversationDefault(newPrompt?.isNewConversationDefault ?? false); - // Find all conversations that have this system prompt as a default - const currenlySelectedConversations = - newPrompt != null - ? Object.values(conversations).filter( - (conversation) => conversation?.apiConfig.defaultSystemPromptId === newPrompt?.id - ) - : []; - setSelectedConversations(currenlySelectedConversations); - }, - [conversations] - ); - - const onSystemPromptDeleted = useCallback((id: string) => { - setUpdatedSystemPrompts((prev) => prev.filter((sp) => sp.id !== id)); - }, []); - - const handleSave = useCallback(() => { - const updatedConversations = getUpdatedConversationWithPrompts(); - onSystemPromptsChange(updatedSystemPrompts, updatedConversations); - }, [onSystemPromptsChange, updatedSystemPrompts, getUpdatedConversationWithPrompts]); - - // useEffects - // Update system prompts on any field change since editing is in place - useEffect(() => { - if (selectedSystemPrompt != null) { - setUpdatedSystemPrompts((prev) => { - const alreadyExists = prev.some((sp) => sp.id === selectedSystemPrompt.id); - if (alreadyExists) { - return prev.map((sp) => { - if (sp.id === selectedSystemPrompt.id) { - return { - ...sp, - content: prompt, - promptType: 'system', - }; - } - return sp; - }); - } else { - return [ - ...prev, - { - ...selectedSystemPrompt, - content: prompt, - promptType: 'system', - }, - ]; - } - }); - } - }, [prompt, selectedSystemPrompt]); - - return ( - - - {i18n.ADD_SYSTEM_PROMPT_MODAL_TITLE} - - - - - - - - - - - - - - - - - {i18n.SYSTEM_PROMPT_DEFAULT_NEW_CONVERSATION} - - - - - } - checked={isNewConversationDefault} - onChange={handleNewConversationDefaultChange} - compressed - /> - - - - - - {i18n.CANCEL} - - - - {i18n.SAVE} - - - - ); - } -); - -SystemPromptModal.displayName = 'SystemPromptModal'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector.tsx index c357c46a56d83..acc99e06e85a5 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector.tsx @@ -29,6 +29,7 @@ interface Props { onSystemPromptDeleted: (systemPromptTitle: string) => void; onSystemPromptSelectionChange: (systemPrompt?: Prompt | string) => void; systemPrompts: Prompt[]; + autoFocus?: boolean; selectedSystemPrompt?: Prompt; } @@ -42,6 +43,7 @@ export type SystemPromptSelectorOption = EuiComboBoxOptionOption<{ */ export const SystemPromptSelector: React.FC = React.memo( ({ + autoFocus = false, systemPrompts, onSystemPromptDeleted, onSystemPromptSelectionChange, @@ -203,9 +205,11 @@ export const SystemPromptSelector: React.FC = React.memo( return ( = React.memo( onChange={onChange} onCreateOption={onCreateOption} renderOption={renderOption} - autoFocus + autoFocus={autoFocus} /> ); } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/translations.ts index 34652bdef8656..41c4a4b535ce7 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/translations.ts @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; export const SYSTEM_PROMPT_SELECTOR = i18n.translate( 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.systemPromptModal.systemPromptSelector.ariaLabel', { - defaultMessage: 'Select to edit, or type to create new', + defaultMessage: 'Select or type to create new...', } ); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_settings.tsx new file mode 100644 index 0000000000000..fa576e20fecba --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_settings.tsx @@ -0,0 +1,264 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; +import { + EuiFormRow, + EuiTextArea, + EuiCheckbox, + EuiIcon, + EuiFlexGroup, + EuiFlexItem, + EuiTitle, + EuiText, + EuiHorizontalRule, + EuiSpacer, +} from '@elastic/eui'; + +import { keyBy } from 'lodash/fp'; + +import { css } from '@emotion/react'; +import { Conversation, Prompt } from '../../../../..'; +import * as i18n from './translations'; +import { UseAssistantContext } from '../../../../assistant_context'; +import { ConversationMultiSelector } from './conversation_multi_selector/conversation_multi_selector'; +import { SystemPromptSelector } from './system_prompt_selector/system_prompt_selector'; +import { TEST_IDS } from '../../../constants'; + +interface Props { + conversationSettings: UseAssistantContext['conversations']; + onSelectedSystemPromptChange: (systemPrompt?: Prompt) => void; + selectedSystemPrompt: Prompt | undefined; + setUpdatedSystemPromptSettings: React.Dispatch>; + setUpdatedConversationSettings: React.Dispatch< + React.SetStateAction + >; + systemPromptSettings: Prompt[]; +} + +/** + * Settings for adding/removing system prompts. Configure name, prompt and default conversations. + */ +export const SystemPromptSettings: React.FC = React.memo( + ({ + conversationSettings, + onSelectedSystemPromptChange, + selectedSystemPrompt, + setUpdatedSystemPromptSettings, + setUpdatedConversationSettings, + systemPromptSettings, + }) => { + // Prompt + const promptContent = useMemo( + () => selectedSystemPrompt?.content ?? '', + [selectedSystemPrompt?.content] + ); + + const handlePromptContentChange = useCallback( + (e: React.ChangeEvent) => { + if (selectedSystemPrompt != null) { + setUpdatedSystemPromptSettings((prev): Prompt[] => { + const alreadyExists = prev.some((sp) => sp.id === selectedSystemPrompt.id); + + if (alreadyExists) { + return prev.map((sp): Prompt => { + if (sp.id === selectedSystemPrompt.id) { + return { + ...sp, + content: e.target.value, + }; + } + return sp; + }); + } + + return prev; + }); + } + }, + [selectedSystemPrompt, setUpdatedSystemPromptSettings] + ); + + // Conversations this system prompt should be a default for + const conversationOptions = useMemo( + () => Object.values(conversationSettings), + [conversationSettings] + ); + const selectedConversations = useMemo(() => { + return selectedSystemPrompt != null + ? Object.values(conversationSettings).filter( + (conversation) => + conversation.apiConfig.defaultSystemPromptId === selectedSystemPrompt.id + ) + : []; + }, [conversationSettings, selectedSystemPrompt]); + + const handleConversationSelectionChange = useCallback( + (currentPromptConversations: Conversation[]) => { + const currentPromptConversationIds = currentPromptConversations.map((convo) => convo.id); + + if (selectedSystemPrompt != null) { + setUpdatedConversationSettings((prev) => + keyBy( + 'id', + /* + * updatedConversationWithPrompts calculates the present of prompt for + * each conversation. Based on the values of selected conversation, it goes + * through each conversation adds/removed the selected prompt on each conversation. + * + * */ + Object.values(prev).map((convo) => ({ + ...convo, + apiConfig: { + ...convo.apiConfig, + defaultSystemPromptId: currentPromptConversationIds.includes(convo.id) + ? selectedSystemPrompt?.id + : convo.apiConfig.defaultSystemPromptId === selectedSystemPrompt?.id + ? // remove the default System Prompt if it is assigned to a conversation + // but that conversation is not in the currentPromptConversationList + // This means conversation was removed in the current transaction + undefined + : // leave it as it is .. if that conversation was neither added nor removed. + convo.apiConfig.defaultSystemPromptId, + }, + })) + ) + ); + } + }, + [selectedSystemPrompt, setUpdatedConversationSettings] + ); + + // Whether this system prompt should be the default for new conversations + const isNewConversationDefault = useMemo( + () => selectedSystemPrompt?.isNewConversationDefault ?? false, + [selectedSystemPrompt?.isNewConversationDefault] + ); + + const handleNewConversationDefaultChange = useCallback( + (e) => { + const isChecked = e.target.checked; + + if (selectedSystemPrompt != null) { + setUpdatedSystemPromptSettings((prev) => { + return prev.map((pp) => { + return { + ...pp, + isNewConversationDefault: selectedSystemPrompt.id === pp.id && isChecked, + }; + }); + }); + } + }, + [selectedSystemPrompt, setUpdatedSystemPromptSettings] + ); + + // When top level system prompt selection changes + const onSystemPromptSelectionChange = useCallback( + (systemPrompt?: Prompt | string) => { + const isNew = typeof systemPrompt === 'string'; + const newSelectedSystemPrompt: Prompt | undefined = isNew + ? { + id: systemPrompt ?? '', + content: '', + name: systemPrompt ?? '', + promptType: 'system', + } + : systemPrompt; + + if (newSelectedSystemPrompt != null) { + setUpdatedSystemPromptSettings((prev) => { + const alreadyExists = prev.some((sp) => sp.id === newSelectedSystemPrompt.id); + + if (!alreadyExists) { + return [...prev, newSelectedSystemPrompt]; + } + + return prev; + }); + } + + onSelectedSystemPromptChange(newSelectedSystemPrompt); + }, + [onSelectedSystemPromptChange, setUpdatedSystemPromptSettings] + ); + + const onSystemPromptDeleted = useCallback( + (id: string) => { + setUpdatedSystemPromptSettings((prev) => prev.filter((sp) => sp.id !== id)); + }, + [setUpdatedSystemPromptSettings] + ); + + return ( + <> + +

{i18n.SETTINGS_TITLE}

+
+ + {i18n.SETTINGS_DESCRIPTION} + + + + + + + + + + + + + + + {i18n.SYSTEM_PROMPT_DEFAULT_NEW_CONVERSATION} + + + + + } + checked={isNewConversationDefault} + onChange={handleNewConversationDefaultChange} + compressed + /> + + + ); + } +); + +SystemPromptSettings.displayName = 'SystemPromptSettings'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/translations.ts index c57e84cd54693..6b7283977b1e2 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/translations.ts @@ -7,49 +7,56 @@ import { i18n } from '@kbn/i18n'; -export const ADD_SYSTEM_PROMPT = i18n.translate( - 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.systemPromptModal.addSystemPromptTitle', +export const SETTINGS_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.settings.settingsTitle', { - defaultMessage: 'Add system prompt...', + defaultMessage: 'System Prompts', + } +); +export const SETTINGS_DESCRIPTION = i18n.translate( + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.settings.settingsDescription', + { + defaultMessage: + 'Create and manage System Prompts. System Prompts are configurable chunks of context that are always sent for a given conversations.', } ); export const ADD_SYSTEM_PROMPT_MODAL_TITLE = i18n.translate( - 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.systemPromptModal.modalTitle', + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.settings.modalTitle', { defaultMessage: 'System Prompts', } ); export const SYSTEM_PROMPT_NAME = i18n.translate( - 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.systemPromptModal.nameLabel', + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.settings.nameLabel', { defaultMessage: 'Name', } ); export const SYSTEM_PROMPT_PROMPT = i18n.translate( - 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.systemPromptModal.promptLabel', + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.settings.promptLabel', { defaultMessage: 'Prompt', } ); export const SYSTEM_PROMPT_DEFAULT_CONVERSATIONS = i18n.translate( - 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.systemPromptModal.defaultConversationsLabel', + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.settings.defaultConversationsLabel', { defaultMessage: 'Default conversations', } ); export const SYSTEM_PROMPT_DEFAULT_NEW_CONVERSATION = i18n.translate( - 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.systemPromptModal.defaultNewConversationTitle', + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.settings.defaultNewConversationTitle', { defaultMessage: 'Use as default for all new conversations', } ); export const SYSTEM_PROMPT_DEFAULT_CONVERSATIONS_HELP_TEXT = i18n.translate( - 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.systemPromptModal.defaultConversationsHelpText', + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.settings.defaultConversationsHelpText', { defaultMessage: 'Conversations that should use this System Prompt by default', } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/add_quick_prompt_modal/add_quick_prompt_modal.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/add_quick_prompt_modal/add_quick_prompt_modal.tsx deleted file mode 100644 index db5243b3a1c12..0000000000000 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/add_quick_prompt_modal/add_quick_prompt_modal.tsx +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, useEffect, useState } from 'react'; -import { - EuiButton, - EuiButtonEmpty, - EuiFormRow, - EuiModal, - EuiModalBody, - EuiModalFooter, - EuiModalHeader, - EuiModalHeaderTitle, - EuiColorPicker, - useColorPickerState, - EuiTextArea, -} from '@elastic/eui'; - -// eslint-disable-next-line @kbn/eslint/module_migration -import styled from 'styled-components'; - -import { EuiSetColorMethod } from '@elastic/eui/src/services/color_picker/color_picker'; -import { PromptContextTemplate } from '../../../..'; -import * as i18n from './translations'; -import { QuickPrompt } from '../types'; -import { QuickPromptSelector } from '../quick_prompt_selector/quick_prompt_selector'; -import { PromptContextSelector } from '../prompt_context_selector/prompt_context_selector'; - -const StyledEuiModal = styled(EuiModal)` - min-width: 400px; - max-width: 400px; - max-height: 80vh; -`; - -const DEFAULT_COLOR = '#D36086'; - -interface Props { - promptContexts: PromptContextTemplate[]; - quickPrompts: QuickPrompt[]; - onQuickPromptsChange: (quickPrompts: QuickPrompt[]) => void; -} - -/** - * Modal for adding/removing quick prompts. Configure name, color, prompt and category. - */ -export const AddQuickPromptModal: React.FC = React.memo( - ({ promptContexts, quickPrompts, onQuickPromptsChange }) => { - const [isModalVisible, setIsModalVisible] = useState(false); - - // Local state for quick prompts (returned to parent on save via onQuickPromptsChange()) - const [updatedQuickPrompts, setUpdatedQuickPrompts] = useState(quickPrompts); - - // Form options - const [selectedQuickPrompt, setSelectedQuickPrompt] = useState(); - // Prompt - const [prompt, setPrompt] = useState(''); - const handlePromptTextChange = useCallback((e: React.ChangeEvent) => { - setPrompt(e.target.value); - }, []); - // Color - const [color, setColor, errors] = useColorPickerState(DEFAULT_COLOR); - const handleColorChange = useCallback( - (text, { hex, isValid }) => { - if (selectedQuickPrompt != null) { - setSelectedQuickPrompt({ - ...selectedQuickPrompt, - color: text, - }); - } - setColor(text, { hex, isValid }); - }, - [selectedQuickPrompt, setColor] - ); - // Prompt Contexts/Categories - const [selectedPromptContexts, setSelectedPromptContexts] = useState( - [] - ); - const onPromptContextSelectionChange = useCallback((pc: PromptContextTemplate[]) => { - setSelectedPromptContexts(pc); - }, []); - - // When top level quick prompt selection changes - const onQuickPromptSelectionChange = useCallback( - (quickPrompt?: QuickPrompt | string) => { - const newQuickPrompt: QuickPrompt | undefined = - typeof quickPrompt === 'string' - ? { - title: quickPrompt ?? '', - prompt: '', - color: DEFAULT_COLOR, - categories: [], - } - : quickPrompt; - - setSelectedQuickPrompt(newQuickPrompt); - setPrompt(newQuickPrompt?.prompt ?? ''); - setColor(newQuickPrompt?.color ?? DEFAULT_COLOR, { - hex: newQuickPrompt?.color ?? DEFAULT_COLOR, - isValid: true, - }); - // Map back to PromptContextTemplate's from QuickPrompt.categories - setSelectedPromptContexts( - promptContexts.filter((bpc) => - newQuickPrompt?.categories?.some((cat) => bpc?.category === cat) - ) ?? [] - ); - }, - [promptContexts, setColor] - ); - - const onQuickPromptDeleted = useCallback((title: string) => { - setUpdatedQuickPrompts((prev) => prev.filter((qp) => qp.title !== title)); - }, []); - - // Modal control functions - const cleanupAndCloseModal = useCallback(() => { - setIsModalVisible(false); - }, []); - - const handleCloseModal = useCallback(() => { - cleanupAndCloseModal(); - }, [cleanupAndCloseModal]); - - const handleSave = useCallback(() => { - onQuickPromptsChange(updatedQuickPrompts); - cleanupAndCloseModal(); - }, [cleanupAndCloseModal, onQuickPromptsChange, updatedQuickPrompts]); - - // useEffects - // Update quick prompts on any field change since editing is in place - useEffect(() => { - if (selectedQuickPrompt != null) { - setUpdatedQuickPrompts((prev) => { - const alreadyExists = prev.some((qp) => qp.title === selectedQuickPrompt.title); - if (alreadyExists) { - return prev.map((qp) => { - const categories = selectedPromptContexts.map((pc) => pc.category); - if (qp.title === selectedQuickPrompt.title) { - return { - ...qp, - color, - prompt, - categories, - }; - } - return qp; - }); - } else { - return [ - ...prev, - { - ...selectedQuickPrompt, - color, - prompt, - categories: selectedPromptContexts.map((pc) => pc.category), - }, - ]; - } - }); - } - }, [color, prompt, selectedPromptContexts, selectedQuickPrompt]); - - // Reset local state on modal open - useEffect(() => { - if (isModalVisible) { - setUpdatedQuickPrompts(quickPrompts); - } - }, [isModalVisible, quickPrompts]); - - return ( - <> - setIsModalVisible(true)} iconType="plus" size="xs"> - {i18n.ADD_QUICK_PROMPT} - - {isModalVisible && ( - - - {i18n.ADD_QUICK_PROMPT_MODAL_TITLE} - - - - - - - - - - - - - - - - - - - - - - {i18n.CANCEL} - - - {i18n.SAVE} - - - - )} - - ); - } -); - -AddQuickPromptModal.displayName = 'AddQuickPromptModal'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/prompt_context_selector/prompt_context_selector.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/prompt_context_selector/prompt_context_selector.tsx index c14d533ee96fa..8cde7aceabbc9 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/prompt_context_selector/prompt_context_selector.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/prompt_context_selector/prompt_context_selector.tsx @@ -12,6 +12,7 @@ import { PromptContextTemplate } from '../../../..'; import * as i18n from './translations'; interface Props { + isDisabled?: boolean; onPromptContextSelectionChange: (promptContexts: PromptContextTemplate[]) => void; promptContexts: PromptContextTemplate[]; selectedPromptContexts?: PromptContextTemplate[]; @@ -23,7 +24,7 @@ export type PromptContextSelectorOption = EuiComboBoxOptionOption<{ category: st * Selector for choosing multiple Prompt Context Categories */ export const PromptContextSelector: React.FC = React.memo( - ({ onPromptContextSelectionChange, promptContexts, selectedPromptContexts = [] }) => { + ({ isDisabled, onPromptContextSelectionChange, promptContexts, selectedPromptContexts = [] }) => { // ComboBox options const options = useMemo( () => @@ -85,6 +86,9 @@ export const PromptContextSelector: React.FC = React.memo( return ( void; onQuickPromptSelectionChange: (quickPrompt?: QuickPrompt | string) => void; quickPrompts: QuickPrompt[]; @@ -34,7 +35,13 @@ export type QuickPromptSelectorOption = EuiComboBoxOptionOption<{ isDefault: boo * Selector for choosing and deleting Quick Prompts */ export const QuickPromptSelector: React.FC = React.memo( - ({ quickPrompts, onQuickPromptDeleted, onQuickPromptSelectionChange, selectedQuickPrompt }) => { + ({ + isDisabled = false, + quickPrompts, + onQuickPromptDeleted, + onQuickPromptSelectionChange, + selectedQuickPrompt, + }) => { // Form options const [options, setOptions] = useState( quickPrompts.map((qp) => ({ @@ -169,6 +176,8 @@ export const QuickPromptSelector: React.FC = React.memo( return ( = React.memo( onChange={onChange} onCreateOption={onCreateOption} renderOption={renderOption} + fullWidth /> ); } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_selector/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_selector/translations.ts index 9cff7417c181b..066463c0eace6 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_selector/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_selector/translations.ts @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; export const QUICK_PROMPT_SELECTOR = i18n.translate( 'xpack.elasticAssistant.assistant.quickPrompts.quickPromptSelector.ariaLabel', { - defaultMessage: 'Select to edit, or type to create new', + defaultMessage: 'Select or type to create new...', } ); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_settings/quick_prompt_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_settings/quick_prompt_settings.tsx new file mode 100644 index 0000000000000..53a7431f3dc3a --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_settings/quick_prompt_settings.tsx @@ -0,0 +1,235 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; +import { + EuiFormRow, + EuiColorPicker, + EuiTextArea, + EuiTitle, + EuiText, + EuiHorizontalRule, + EuiSpacer, +} from '@elastic/eui'; + +import { EuiSetColorMethod } from '@elastic/eui/src/services/color_picker/color_picker'; +import { css } from '@emotion/react'; +import { PromptContextTemplate } from '../../../..'; +import * as i18n from './translations'; +import { QuickPrompt } from '../types'; +import { QuickPromptSelector } from '../quick_prompt_selector/quick_prompt_selector'; +import { PromptContextSelector } from '../prompt_context_selector/prompt_context_selector'; +import { useAssistantContext } from '../../../assistant_context'; + +const DEFAULT_COLOR = '#D36086'; + +interface Props { + onSelectedQuickPromptChange: (quickPrompt?: QuickPrompt) => void; + quickPromptSettings: QuickPrompt[]; + selectedQuickPrompt: QuickPrompt | undefined; + setUpdatedQuickPromptSettings: React.Dispatch>; +} + +/** + * Settings adding/removing quick prompts. Configure name, color, prompt and category. + */ +export const QuickPromptSettings: React.FC = React.memo( + ({ + onSelectedQuickPromptChange, + quickPromptSettings, + selectedQuickPrompt, + setUpdatedQuickPromptSettings, + }) => { + const { basePromptContexts } = useAssistantContext(); + + // Prompt + const prompt = useMemo(() => selectedQuickPrompt?.prompt ?? '', [selectedQuickPrompt?.prompt]); + + const handlePromptChange = useCallback( + (e: React.ChangeEvent) => { + if (selectedQuickPrompt != null) { + setUpdatedQuickPromptSettings((prev) => { + const alreadyExists = prev.some((qp) => qp.title === selectedQuickPrompt.title); + + if (alreadyExists) { + return prev.map((qp) => { + if (qp.title === selectedQuickPrompt.title) { + return { + ...qp, + prompt: e.target.value, + }; + } + return qp; + }); + } + + return prev; + }); + } + }, + [selectedQuickPrompt, setUpdatedQuickPromptSettings] + ); + + // Color + const selectedColor = useMemo( + () => selectedQuickPrompt?.color ?? DEFAULT_COLOR, + [selectedQuickPrompt?.color] + ); + + const handleColorChange = useCallback( + (color, { hex, isValid }) => { + if (selectedQuickPrompt != null) { + setUpdatedQuickPromptSettings((prev) => { + const alreadyExists = prev.some((qp) => qp.title === selectedQuickPrompt.title); + + if (alreadyExists) { + return prev.map((qp) => { + if (qp.title === selectedQuickPrompt.title) { + return { + ...qp, + color, + }; + } + return qp; + }); + } + return prev; + }); + } + }, + [selectedQuickPrompt, setUpdatedQuickPromptSettings] + ); + + // Prompt Contexts + const selectedPromptContexts = useMemo( + () => + basePromptContexts.filter((bpc) => + selectedQuickPrompt?.categories?.some((cat) => bpc?.category === cat) + ) ?? [], + [basePromptContexts, selectedQuickPrompt?.categories] + ); + + const onPromptContextSelectionChange = useCallback( + (pc: PromptContextTemplate[]) => { + if (selectedQuickPrompt != null) { + setUpdatedQuickPromptSettings((prev) => { + const alreadyExists = prev.some((qp) => qp.title === selectedQuickPrompt.title); + + if (alreadyExists) { + return prev.map((qp) => { + if (qp.title === selectedQuickPrompt.title) { + return { + ...qp, + categories: pc.map((p) => p.category), + }; + } + return qp; + }); + } + return prev; + }); + } + }, + [selectedQuickPrompt, setUpdatedQuickPromptSettings] + ); + + // When top level quick prompt selection changes + const onQuickPromptSelectionChange = useCallback( + (quickPrompt?: QuickPrompt | string) => { + const isNew = typeof quickPrompt === 'string'; + const newSelectedQuickPrompt: QuickPrompt | undefined = isNew + ? { + title: quickPrompt ?? '', + prompt: '', + color: DEFAULT_COLOR, + categories: [], + } + : quickPrompt; + + if (newSelectedQuickPrompt != null) { + setUpdatedQuickPromptSettings((prev) => { + const alreadyExists = prev.some((qp) => qp.title === newSelectedQuickPrompt.title); + + if (!alreadyExists) { + return [...prev, newSelectedQuickPrompt]; + } + + return prev; + }); + } + + onSelectedQuickPromptChange(newSelectedQuickPrompt); + }, + [onSelectedQuickPromptChange, setUpdatedQuickPromptSettings] + ); + + const onQuickPromptDeleted = useCallback( + (title: string) => { + setUpdatedQuickPromptSettings((prev) => prev.filter((qp) => qp.title !== title)); + }, + [setUpdatedQuickPromptSettings] + ); + + return ( + <> + +

{i18n.SETTINGS_TITLE}

+
+ + {i18n.SETTINGS_DESCRIPTION} + + + + + + + + + + + + + + + + + + + ); + } +); + +QuickPromptSettings.displayName = 'AddQuickPromptModal'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/add_quick_prompt_modal/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_settings/translations.ts similarity index 54% rename from x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/add_quick_prompt_modal/translations.ts rename to x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_settings/translations.ts index 72ada2e7ad0fd..e388f2fe1d884 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/add_quick_prompt_modal/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_settings/translations.ts @@ -7,49 +7,57 @@ import { i18n } from '@kbn/i18n'; -export const ADD_QUICK_PROMPT = i18n.translate( - 'xpack.elasticAssistant.assistant.quickPrompts.addQuickPromptModal.addQuickPromptTitle', +export const SETTINGS_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.quickPrompts.settings.settingsTitle', { - defaultMessage: 'Add quick prompt...', + defaultMessage: 'Quick Prompts', + } +); + +export const SETTINGS_DESCRIPTION = i18n.translate( + 'xpack.elasticAssistant.assistant.quickPrompts.settings.settingsDescription', + { + defaultMessage: + 'Create and manage Quick Prompts. Quick Prompts are shortcuts to common actions.', } ); export const ADD_QUICK_PROMPT_MODAL_TITLE = i18n.translate( - 'xpack.elasticAssistant.assistant.quickPrompts.addQuickPromptModal.modalTitle', + 'xpack.elasticAssistant.assistant.quickPrompts.settings.modalTitle', { defaultMessage: 'Quick Prompts', } ); export const QUICK_PROMPT_NAME = i18n.translate( - 'xpack.elasticAssistant.assistant.quickPrompts.addQuickPromptModal.nameLabel', + 'xpack.elasticAssistant.assistant.quickPrompts.settings.nameLabel', { defaultMessage: 'Name', } ); export const QUICK_PROMPT_PROMPT = i18n.translate( - 'xpack.elasticAssistant.assistant.quickPrompts.addQuickPromptModal.promptLabel', + 'xpack.elasticAssistant.assistant.quickPrompts.settings.promptLabel', { defaultMessage: 'Prompt', } ); export const QUICK_PROMPT_BADGE_COLOR = i18n.translate( - 'xpack.elasticAssistant.assistant.quickPrompts.addQuickPromptModal.badgeColorLabel', + 'xpack.elasticAssistant.assistant.quickPrompts.settings.badgeColorLabel', { defaultMessage: 'Badge color', } ); -export const QUICK_PROMPT_CATEGORIES = i18n.translate( - 'xpack.elasticAssistant.assistant.quickPrompts.addQuickPromptModal.categoriesLabel', +export const QUICK_PROMPT_CONTEXTS = i18n.translate( + 'xpack.elasticAssistant.assistant.quickPrompts.settings.contextsLabel', { - defaultMessage: 'Categories', + defaultMessage: 'Contexts', } ); -export const QUICK_PROMPT_CATEGORIES_HELP_TEXT = i18n.translate( - 'xpack.elasticAssistant.assistant.quickPrompts.addQuickPromptModal.categoriesHelpText', +export const QUICK_PROMPT_CONTEXTS_HELP_TEXT = i18n.translate( + 'xpack.elasticAssistant.assistant.quickPrompts.settings.contextsHelpText', { defaultMessage: 'Select the Prompt Contexts that this Quick Prompt will be available for. Selecting none will make this Quick Prompt available at all times.', diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.tsx index d66ed24d2426a..f4b858ee796f1 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompts.tsx @@ -6,14 +6,13 @@ */ import React, { useCallback, useMemo, useState } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiBadge, EuiPopover } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiBadge, EuiPopover, EuiButtonEmpty } from '@elastic/eui'; // eslint-disable-next-line @kbn/eslint/module_migration import styled from 'styled-components'; -import { QuickPrompt } from '../../..'; import * as i18n from './translations'; -import { AddQuickPromptModal } from './add_quick_prompt_modal/add_quick_prompt_modal'; import { useAssistantContext } from '../../assistant_context'; +import { QUICK_PROMPTS_TAB } from '../settings/assistant_settings'; const QuickPromptsFlexGroup = styled(EuiFlexGroup)` margin: 16px; @@ -30,7 +29,7 @@ interface QuickPromptsProps { * and localstorage for storing new and edited prompts. */ export const QuickPrompts: React.FC = React.memo(({ setInput }) => { - const { allQuickPrompts, basePromptContexts, promptContexts, setAllQuickPrompts } = + const { allQuickPrompts, promptContexts, setIsSettingsModalVisible, setSelectedSettingsTab } = useAssistantContext(); const contextFilteredQuickPrompts = useMemo(() => { @@ -62,13 +61,12 @@ export const QuickPrompts: React.FC = React.memo(({ setInput }, [closeOverflowPopover, setInput] ); - // Callback for manage modal, saves to local storage on change - const onQuickPromptsChange = useCallback( - (newQuickPrompts: QuickPrompt[]) => { - setAllQuickPrompts(newQuickPrompts); - }, - [setAllQuickPrompts] - ); + + const showQuickPromptSettings = useCallback(() => { + setIsSettingsModalVisible(true); + setSelectedSettingsTab(QUICK_PROMPTS_TAB); + }, [setIsSettingsModalVisible, setSelectedSettingsTab]); + return ( {contextFilteredQuickPrompts.slice(0, COUNT_BEFORE_OVERFLOW).map((badge, index) => ( @@ -114,11 +112,9 @@ export const QuickPrompts: React.FC = React.memo(({ setInput )} - + + {i18n.ADD_QUICK_PROMPT} + ); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/translations.ts index e2d3fd5ef7824..38d5fdb0950c4 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/translations.ts @@ -7,6 +7,12 @@ import { i18n } from '@kbn/i18n'; +export const ADD_QUICK_PROMPT = i18n.translate( + 'xpack.elasticAssistant.assistant.quickPrompts.addQuickPromptTitle', + { + defaultMessage: 'Add quick prompt...', + } +); export const QUICK_PROMPT_OVERFLOW_ARIA = i18n.translate( 'xpack.elasticAssistant.assistant.quickPrompts.overflowAriaTitle', { diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/advanced_settings/advanced_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/advanced_settings/advanced_settings.tsx new file mode 100644 index 0000000000000..ded138fcc2b62 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/advanced_settings/advanced_settings.tsx @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiFormRow, EuiTitle, EuiText, EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; + +import * as i18n from './translations'; + +interface Props { + onAdvancedSettingsChange?: () => void; +} + +/** + * Advanced Settings -- your catch-all container for settings that don't have a home elsewhere. + */ +export const AdvancedSettings: React.FC = React.memo(({ onAdvancedSettingsChange }) => { + return ( + <> + +

{i18n.SETTINGS_TITLE}

+
+ + + {i18n.SETTINGS_DESCRIPTION} + + + + + <>{'Disable LocalStorage'} + + + <>{'Clear LocalStorage'} + + + <>{'Reset Something Else'} + + + ); +}); + +AdvancedSettings.displayName = 'AdvancedSettings'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/advanced_settings/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/advanced_settings/translations.ts new file mode 100644 index 0000000000000..64642e97b8cc5 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/advanced_settings/translations.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const SETTINGS_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.advancedSettings.settingsTitle', + { + defaultMessage: 'Advanced Settings', + } +); +export const SETTINGS_DESCRIPTION = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.advancedSettings.settingsDescription', + { + defaultMessage: "They're not further along, they just have a different set of problems.", + } +); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/assistant_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/assistant_settings.tsx new file mode 100644 index 0000000000000..7fb8d0cff7c3a --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/assistant_settings.tsx @@ -0,0 +1,315 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useEffect, useState } from 'react'; +import { + EuiButton, + EuiButtonEmpty, + EuiIcon, + EuiModal, + EuiModalFooter, + EuiKeyPadMenu, + EuiKeyPadMenuItem, + EuiPage, + EuiPageBody, + EuiPageSidebar, + EuiSplitPanel, +} from '@elastic/eui'; + +// eslint-disable-next-line @kbn/eslint/module_migration +import styled from 'styled-components'; +import { css } from '@emotion/react'; +import { Conversation, Prompt, QuickPrompt } from '../../..'; +import * as i18n from './translations'; +import { useAssistantContext } from '../../assistant_context'; +import { AnonymizationSettings } from '../../data_anonymization/settings/anonymization_settings'; +import { QuickPromptSettings } from '../quick_prompts/quick_prompt_settings/quick_prompt_settings'; +import { SystemPromptSettings } from '../prompt_editor/system_prompt/system_prompt_modal/system_prompt_settings'; +import { AdvancedSettings } from './advanced_settings/advanced_settings'; +import { ConversationSettings } from '../conversations/conversation_settings/conversation_settings'; +import { TEST_IDS } from '../constants'; +import { useSettingsUpdater } from './use_settings_updater/use_settings_updater'; + +const StyledEuiModal = styled(EuiModal)` + width: 800px; + height: 575px; +`; + +export const CONVERSATIONS_TAB = 'CONVERSATION_TAB' as const; +export const QUICK_PROMPTS_TAB = 'QUICK_PROMPTS_TAB' as const; +export const SYSTEM_PROMPTS_TAB = 'SYSTEM_PROMPTS_TAB' as const; +export const ANONYMIZATION_TAB = 'ANONYMIZATION_TAB' as const; +export const FUNCTIONS_TAB = 'FUNCTIONS_TAB' as const; +export const ADVANCED_TAB = 'ADVANCED_TAB' as const; + +export type SettingsTabs = + | typeof CONVERSATIONS_TAB + | typeof QUICK_PROMPTS_TAB + | typeof SYSTEM_PROMPTS_TAB + | typeof ANONYMIZATION_TAB + | typeof FUNCTIONS_TAB + | typeof ADVANCED_TAB; +interface Props { + onClose: ( + event?: React.KeyboardEvent | React.MouseEvent + ) => void; + onSave: () => void; + selectedConversation: Conversation; + setSelectedConversationId: React.Dispatch>; +} + +/** + * Modal for overall Assistant Settings, including conversation settings, quick prompts, system prompts, + * anonymization, functions (coming soon!), and advanced settings. + */ +export const AssistantSettings: React.FC = React.memo( + ({ + onClose, + onSave, + selectedConversation: defaultSelectedConversation, + setSelectedConversationId, + }) => { + const { actionTypeRegistry, http, selectedSettingsTab, setSelectedSettingsTab } = + useAssistantContext(); + const { + conversationSettings, + defaultAllow, + defaultAllowReplacement, + quickPromptSettings, + systemPromptSettings, + setUpdatedConversationSettings, + setUpdatedDefaultAllow, + setUpdatedDefaultAllowReplacement, + setUpdatedQuickPromptSettings, + setUpdatedSystemPromptSettings, + saveSettings, + } = useSettingsUpdater(); + + // Local state for saving previously selected items so tab switching is friendlier + // Conversation Selection State + const [selectedConversation, setSelectedConversation] = useState( + () => { + return conversationSettings[defaultSelectedConversation.id]; + } + ); + const onHandleSelectedConversationChange = useCallback((conversation?: Conversation) => { + setSelectedConversation(conversation); + }, []); + useEffect(() => { + if (selectedConversation != null) { + setSelectedConversation(conversationSettings[selectedConversation.id]); + } + }, [conversationSettings, selectedConversation]); + + // Quick Prompt Selection State + const [selectedQuickPrompt, setSelectedQuickPrompt] = useState(); + const onHandleSelectedQuickPromptChange = useCallback((quickPrompt?: QuickPrompt) => { + setSelectedQuickPrompt(quickPrompt); + }, []); + useEffect(() => { + if (selectedQuickPrompt != null) { + setSelectedQuickPrompt( + quickPromptSettings.find((q) => q.title === selectedQuickPrompt.title) + ); + } + }, [quickPromptSettings, selectedQuickPrompt]); + + // System Prompt Selection State + const [selectedSystemPrompt, setSelectedSystemPrompt] = useState(); + const onHandleSelectedSystemPromptChange = useCallback((systemPrompt?: Prompt) => { + setSelectedSystemPrompt(systemPrompt); + }, []); + useEffect(() => { + if (selectedSystemPrompt != null) { + setSelectedSystemPrompt(systemPromptSettings.find((p) => p.id === selectedSystemPrompt.id)); + } + }, [selectedSystemPrompt, systemPromptSettings]); + + const handleSave = useCallback(() => { + // If the selected conversation is deleted, we need to select a new conversation to prevent a crash creating a conversation that already exists + const isSelectedConversationDeleted = + conversationSettings[defaultSelectedConversation.id] == null; + const newSelectedConversationId: string | undefined = Object.keys(conversationSettings)[0]; + if (isSelectedConversationDeleted && newSelectedConversationId != null) { + setSelectedConversationId(conversationSettings[newSelectedConversationId].id); + } + saveSettings(); + onSave(); + }, [ + conversationSettings, + defaultSelectedConversation.id, + onSave, + saveSettings, + setSelectedConversationId, + ]); + + return ( + + + + + setSelectedSettingsTab(CONVERSATIONS_TAB)} + > + <> + + + + + setSelectedSettingsTab(QUICK_PROMPTS_TAB)} + > + <> + + + + + setSelectedSettingsTab(SYSTEM_PROMPTS_TAB)} + > + + + + setSelectedSettingsTab(ANONYMIZATION_TAB)} + > + + + + + + + + {selectedSettingsTab === CONVERSATIONS_TAB && ( + + )} + {selectedSettingsTab === QUICK_PROMPTS_TAB && ( + + )} + {selectedSettingsTab === SYSTEM_PROMPTS_TAB && ( + + )} + {selectedSettingsTab === ANONYMIZATION_TAB && ( + + )} + {selectedSettingsTab === FUNCTIONS_TAB && <>} + {selectedSettingsTab === ADVANCED_TAB && } + + + + + {i18n.CANCEL} + + + + {i18n.SAVE} + + + + + + + + ); + } +); + +AssistantSettings.displayName = 'AssistantSettings'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/assistant_settings_button.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/assistant_settings_button.tsx new file mode 100644 index 0000000000000..e3ba463b387db --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/assistant_settings_button.tsx @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback } from 'react'; +import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; + +import { Conversation } from '../../..'; +import { AssistantSettings, CONVERSATIONS_TAB } from './assistant_settings'; +import * as i18n from './translations'; +import { useAssistantContext } from '../../assistant_context'; + +interface Props { + selectedConversation: Conversation; + setSelectedConversationId: React.Dispatch>; + isDisabled?: boolean; +} + +/** + * Gear button that opens the assistant settings modal + */ +export const AssistantSettingsButton: React.FC = React.memo( + ({ isDisabled = false, selectedConversation, setSelectedConversationId }) => { + const { isSettingsModalVisible, setIsSettingsModalVisible, setSelectedSettingsTab } = + useAssistantContext(); + + // Modal control functions + const cleanupAndCloseModal = useCallback(() => { + setIsSettingsModalVisible(false); + }, [setIsSettingsModalVisible]); + + const handleCloseModal = useCallback(() => { + cleanupAndCloseModal(); + }, [cleanupAndCloseModal]); + + const handleSave = useCallback(() => { + cleanupAndCloseModal(); + }, [cleanupAndCloseModal]); + + const handleShowConversationSettings = useCallback(() => { + setSelectedSettingsTab(CONVERSATIONS_TAB); + setIsSettingsModalVisible(true); + }, [setIsSettingsModalVisible, setSelectedSettingsTab]); + + return ( + <> + + + + + {isSettingsModalVisible && ( + + )} + + ); + } +); + +AssistantSettingsButton.displayName = 'AssistantSettingsButton'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/translations.ts new file mode 100644 index 0000000000000..157e9321a70c6 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/translations.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const SETTINGS = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.settingsAriaLabel', + { + defaultMessage: 'Settings', + } +); + +export const SETTINGS_TOOLTIP = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.settingsTooltip', + { + defaultMessage: 'Settings', + } +); + +export const CONVERSATIONS_MENU_ITEM = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.settingsConversationsMenuItemTitle', + { + defaultMessage: 'Conversations', + } +); + +export const QUICK_PROMPTS_MENU_ITEM = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.settingsQuickPromptsMenuItemTitle', + { + defaultMessage: 'Quick Prompts', + } +); + +export const SYSTEM_PROMPTS_MENU_ITEM = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.settingsSystemPromptsMenuItemTitle', + { + defaultMessage: 'System Prompts', + } +); + +export const ANONYMIZATION_MENU_ITEM = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.settingsAnonymizationMenuItemTitle', + { + defaultMessage: 'Anonymization', + } +); + +export const FUNCTIONS_MENU_ITEM = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.settingsFunctionsMenuItemTitle', + { + defaultMessage: 'Functions', + } +); + +export const ADVANCED_MENU_ITEM = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.settingsAdvancedMenuItemTitle', + { + defaultMessage: 'Advanced', + } +); + +export const ADD_SYSTEM_PROMPT_MODAL_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.settings.modalTitle', + { + defaultMessage: 'System Prompts', + } +); + +export const CANCEL = i18n.translate( + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.slCancelButtonTitle', + { + defaultMessage: 'Cancel', + } +); + +export const SAVE = i18n.translate( + 'xpack.elasticAssistant.assistant.promptEditor.systemPrompt.slSaveButtonTitle', + { + defaultMessage: 'Save', + } +); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.tsx new file mode 100644 index 0000000000000..e40ae00b69720 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/use_settings_updater/use_settings_updater.tsx @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useState } from 'react'; +import { Prompt, QuickPrompt } from '../../../..'; +import { UseAssistantContext, useAssistantContext } from '../../../assistant_context'; + +interface UseSettingsUpdater { + conversationSettings: UseAssistantContext['conversations']; + defaultAllow: string[]; + defaultAllowReplacement: string[]; + quickPromptSettings: QuickPrompt[]; + resetSettings: () => void; + systemPromptSettings: Prompt[]; + setUpdatedDefaultAllow: React.Dispatch>; + setUpdatedDefaultAllowReplacement: React.Dispatch>; + setUpdatedConversationSettings: React.Dispatch< + React.SetStateAction + >; + setUpdatedQuickPromptSettings: React.Dispatch>; + setUpdatedSystemPromptSettings: React.Dispatch>; + saveSettings: () => void; +} + +export const useSettingsUpdater = (): UseSettingsUpdater => { + // Initial state from assistant context + const { + allQuickPrompts, + allSystemPrompts, + conversations, + defaultAllow, + defaultAllowReplacement, + setAllQuickPrompts, + setAllSystemPrompts, + setConversations, + setDefaultAllow, + setDefaultAllowReplacement, + } = useAssistantContext(); + + /** + * Pending updating state + */ + // Conversations + const [updatedConversationSettings, setUpdatedConversationSettings] = + useState(conversations); + // Quick Prompts + const [updatedQuickPromptSettings, setUpdatedQuickPromptSettings] = + useState(allQuickPrompts); + // System Prompts + const [updatedSystemPromptSettings, setUpdatedSystemPromptSettings] = + useState(allSystemPrompts); + // Anonymization + const [updatedDefaultAllow, setUpdatedDefaultAllow] = useState(defaultAllow); + const [updatedDefaultAllowReplacement, setUpdatedDefaultAllowReplacement] = + useState(defaultAllowReplacement); + + /** + * Reset all pending settings + */ + const resetSettings = useCallback((): void => { + setUpdatedConversationSettings(conversations); + setUpdatedQuickPromptSettings(allQuickPrompts); + setUpdatedSystemPromptSettings(allSystemPrompts); + setUpdatedDefaultAllow(defaultAllow); + setUpdatedDefaultAllowReplacement(defaultAllowReplacement); + }, [allQuickPrompts, allSystemPrompts, conversations, defaultAllow, defaultAllowReplacement]); + + /** + * Save all pending settings + */ + const saveSettings = useCallback((): void => { + setAllQuickPrompts(updatedQuickPromptSettings); + setAllSystemPrompts(updatedSystemPromptSettings); + setConversations(updatedConversationSettings); + setDefaultAllow(updatedDefaultAllow); + setDefaultAllowReplacement(updatedDefaultAllowReplacement); + }, [ + setAllQuickPrompts, + setAllSystemPrompts, + setConversations, + setDefaultAllow, + setDefaultAllowReplacement, + updatedConversationSettings, + updatedDefaultAllow, + updatedDefaultAllowReplacement, + updatedQuickPromptSettings, + updatedSystemPromptSettings, + ]); + + return { + conversationSettings: updatedConversationSettings, + defaultAllow: updatedDefaultAllow, + defaultAllowReplacement: updatedDefaultAllowReplacement, + quickPromptSettings: updatedQuickPromptSettings, + resetSettings, + systemPromptSettings: updatedSystemPromptSettings, + saveSettings, + setUpdatedDefaultAllow, + setUpdatedDefaultAllowReplacement, + setUpdatedConversationSettings, + setUpdatedQuickPromptSettings, + setUpdatedSystemPromptSettings, + }; +}; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/streaming_text/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/streaming_text/index.tsx index 33dca8c6e3609..83e6c3e64fd52 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/streaming_text/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/streaming_text/index.tsx @@ -17,8 +17,10 @@ export interface StreamingTextProps { export const StreamingText: React.FC = React.memo( ({ text, children, chunkSize = 5, delay = 100, onStreamingComplete }) => { - const [displayText, setDisplayText] = useState(delay === 0 ? text : ''); - const [isStreamingComplete, setIsStreamingComplete] = useState(delay === 0); + const [displayText, setDisplayText] = useState(delay > 0 ? '' : text); + const [isStreamingComplete, setIsStreamingComplete] = useState( + delay == null || delay === 0 + ); useEffect(() => { if (delay === 0) { @@ -30,6 +32,7 @@ export const StreamingText: React.FC = React.memo { if (isStreamingComplete || delay === 0) { + setDisplayText(text); return; } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/translations.ts index 1b5c24dff00d6..580e02247e3ee 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/translations.ts @@ -18,46 +18,6 @@ export const DEFAULT_ASSISTANT_TITLE = i18n.translate( } ); -export const MISSING_CONNECTOR_CALLOUT_TITLE = i18n.translate( - 'xpack.elasticAssistant.assistant.missingConnectorCalloutTitle', - { - defaultMessage: 'The current conversation is missing a connector configuration', - } -); - -export const MISSING_CONNECTOR_CALLOUT_DESCRIPTION = i18n.translate( - 'xpack.elasticAssistant.assistant.missingConnectorCalloutDescription', - { - defaultMessage: 'Select a connector from the conversation settings to continue', - } -); - -// Settings -export const SETTINGS_TITLE = i18n.translate('xpack.elasticAssistant.assistant.settingsTitle', { - defaultMessage: 'Conversation settings', -}); - -export const SETTINGS_CONNECTOR_TITLE = i18n.translate( - 'xpack.elasticAssistant.assistant.settings.connectorTitle', - { - defaultMessage: 'Connector', - } -); - -export const SETTINGS_PROMPT_TITLE = i18n.translate( - 'xpack.elasticAssistant.assistant.settings.promptTitle', - { - defaultMessage: 'System prompt', - } -); - -export const SETTINGS_PROMPT_HELP_TEXT_TITLE = i18n.translate( - 'xpack.elasticAssistant.assistant.settings.promptHelpTextTitle', - { - defaultMessage: 'Context provided before every conversation', - } -); - export const SHOW_ANONYMIZED = i18n.translate( 'xpack.elasticAssistant.assistant.settings.showAnonymizedToggleLabel', { diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/sample_conversations.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/sample_conversations.tsx index 60bb89c4e355f..033d81197ce94 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/sample_conversations.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/use_conversation/sample_conversations.tsx @@ -126,11 +126,6 @@ export const BASE_CONVERSATIONS: Record = { stream: true, }, }, - // { - // role: 'assistant', - // content: i18n.WELCOME_NO_CONNECTOR_PRIVILEGES, - // timestamp: '', - // }, ], apiConfig: {}, }, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx index 3bce0e7f86041..f0a9b552a2be3 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/index.tsx @@ -32,6 +32,7 @@ import { QUICK_PROMPT_LOCAL_STORAGE_KEY, SYSTEM_PROMPT_LOCAL_STORAGE_KEY, } from './constants'; +import { CONVERSATIONS_TAB, SettingsTabs } from '../assistant/settings/assistant_settings'; export interface ShowAssistantOverlayProps { showOverlay: boolean; @@ -74,7 +75,7 @@ interface AssistantProviderProps { title?: string; } -interface UseAssistantContext { +export interface UseAssistantContext { actionTypeRegistry: ActionTypeRegistryContract; augmentMessageCodeBlocks: (currentConversation: Conversation) => CodeBlockDetails[][]; allQuickPrompts: QuickPrompt[]; @@ -100,16 +101,20 @@ interface UseAssistantContext { showAnonymizedValues: boolean; }) => EuiCommentProps[]; http: HttpSetup; + isSettingsModalVisible: boolean; localStorageLastConversationId: string | undefined; promptContexts: Record; nameSpace: string; registerPromptContext: RegisterPromptContext; + selectedSettingsTab: SettingsTabs; setAllQuickPrompts: React.Dispatch>; setAllSystemPrompts: React.Dispatch>; setConversations: React.Dispatch>>; setDefaultAllow: React.Dispatch>; setDefaultAllowReplacement: React.Dispatch>; + setIsSettingsModalVisible: React.Dispatch>; setLastConversationId: React.Dispatch>; + setSelectedSettingsTab: React.Dispatch>; setShowAssistantOverlay: (showAssistantOverlay: ShowAssistantOverlay) => void; showAssistantOverlay: ShowAssistantOverlay; title: string; @@ -204,6 +209,12 @@ export const AssistantProvider: React.FC = ({ (showAssistant) => {} ); + /** + * Settings State + */ + const [isSettingsModalVisible, setIsSettingsModalVisible] = useState(false); + const [selectedSettingsTab, setSelectedSettingsTab] = useState(CONVERSATIONS_TAB); + const [conversations, setConversationsInternal] = useState(getInitialConversations()); const conversationIds = useMemo(() => Object.keys(conversations).sort(), [conversations]); @@ -253,14 +264,18 @@ export const AssistantProvider: React.FC = ({ docLinks, getComments, http, + isSettingsModalVisible, promptContexts, nameSpace, registerPromptContext, + selectedSettingsTab, setAllQuickPrompts: setLocalStorageQuickPrompts, setAllSystemPrompts: setLocalStorageSystemPrompts, setConversations: onConversationsUpdated, setDefaultAllow, setDefaultAllowReplacement, + setIsSettingsModalVisible, + setSelectedSettingsTab, setShowAssistantOverlay, showAssistantOverlay, title, @@ -283,6 +298,7 @@ export const AssistantProvider: React.FC = ({ docLinks, getComments, http, + isSettingsModalVisible, localStorageLastConversationId, localStorageQuickPrompts, localStorageSystemPrompts, @@ -290,11 +306,14 @@ export const AssistantProvider: React.FC = ({ onConversationsUpdated, promptContexts, registerPromptContext, + selectedSettingsTab, setDefaultAllow, setDefaultAllowReplacement, + setIsSettingsModalVisible, setLocalStorageLastConversationId, setLocalStorageQuickPrompts, setLocalStorageSystemPrompts, + setSelectedSettingsTab, showAssistantOverlay, title, unRegisterPromptContext, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx index e0b0ff128cfa0..dd31844938e7f 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx @@ -47,6 +47,7 @@ export interface Conversation { connectorId?: string; defaultSystemPromptId?: string; provider?: OpenAiProviderType; + model?: string; }; id: string; messages: Message[]; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_button/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_button/index.tsx index 51150264c7988..a70ab2a16e5cb 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_button/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_button/index.tsx @@ -13,7 +13,6 @@ import * as i18n from '../translations'; export interface ConnectorButtonProps { setIsConnectorModalVisible: React.Dispatch>; - connectorAdded?: boolean; } /** @@ -22,18 +21,15 @@ export interface ConnectorButtonProps { * connector add logic. */ export const ConnectorButton: React.FC = React.memo( - ({ setIsConnectorModalVisible, connectorAdded = false }) => { + ({ setIsConnectorModalVisible }) => { return ( } - title={connectorAdded ? i18n.CONNECTOR_ADDED_TITLE : i18n.ADD_CONNECTOR_TITLE} - isDisabled={connectorAdded} - description={ - connectorAdded ? i18n.CONNECTOR_ADDED_DESCRIPTION : i18n.ADD_CONNECTOR_DESCRIPTION - } + title={i18n.ADD_CONNECTOR_TITLE} + description={i18n.ADD_CONNECTOR_DESCRIPTION} onClick={() => setIsConnectorModalVisible(true)} /> diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_missing_callout/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_missing_callout/index.tsx new file mode 100644 index 0000000000000..99e8d98b438b2 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_missing_callout/index.tsx @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback } from 'react'; +import { EuiCallOut, EuiLink } from '@elastic/eui'; + +import { FormattedMessage } from '@kbn/i18n-react'; +import * as i18n from '../translations'; +import { useAssistantContext } from '../../assistant_context'; +import { CONVERSATIONS_TAB } from '../../assistant/settings/assistant_settings'; + +/** + * Error callout to be displayed when there is no connector configured for a conversation. Includes deep-link + * to conversation settings to quickly resolve. + * + * TODO: Add 'quick fix' button to just pick a connector + * TODO: Add setting for 'default connector' so we can auto-resolve and not even show this + */ +export const ConnectorMissingCallout: React.FC = React.memo(() => { + const { isSettingsModalVisible, setIsSettingsModalVisible, setSelectedSettingsTab } = + useAssistantContext(); + + const onConversationSettingsClicked = useCallback(() => { + if (!isSettingsModalVisible) { + setIsSettingsModalVisible(true); + setSelectedSettingsTab(CONVERSATIONS_TAB); + } + }, [isSettingsModalVisible, setIsSettingsModalVisible, setSelectedSettingsTab]); + + return ( + +

+ {' '} + + {i18n.MISSING_CONNECTOR_CONVERSATION_SETTINGS_LINK} + + ), + }} + /> +

+
+ ); +}); +ConnectorMissingCallout.displayName = 'ConnectorMissingCallout'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_selector/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_selector/index.tsx index 010b4be5ad4b0..870952dde56b5 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_selector/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_selector/index.tsx @@ -20,17 +20,17 @@ import { GEN_AI_CONNECTOR_ID, OpenAiProviderType, } from '@kbn/stack-connectors-plugin/public/common'; -import { Conversation } from '../../assistant_context/types'; import { useLoadConnectors } from '../use_load_connectors'; -import { useConversation } from '../../assistant/use_conversation'; import * as i18n from '../translations'; import { useLoadActionTypes } from '../use_load_action_types'; export const ADD_NEW_CONNECTOR = 'ADD_NEW_CONNECTOR'; interface Props { actionTypeRegistry: ActionTypeRegistryContract; - conversation: Conversation; http: HttpSetup; + isDisabled?: boolean; + onConnectorSelectionChange: (connectorId: string, provider: OpenAiProviderType) => void; + selectedConnectorId?: string; onConnectorModalVisibilityChange?: (isVisible: boolean) => void; } @@ -39,9 +39,14 @@ interface Config { } export const ConnectorSelector: React.FC = React.memo( - ({ actionTypeRegistry, conversation, http, onConnectorModalVisibilityChange }) => { - const { setApiConfig } = useConversation(); - + ({ + actionTypeRegistry, + http, + isDisabled = false, + onConnectorModalVisibilityChange, + selectedConnectorId, + onConnectorSelectionChange, + }) => { // Connector Modal State const [isConnectorModalVisible, setIsConnectorModalVisible] = useState(false); const { data: actionTypes } = useLoadActionTypes({ http }); @@ -124,49 +129,33 @@ export const ConnectorSelector: React.FC = React.memo( const apiProvider = ( connectors?.find((c) => c.id === connectorId) as ActionConnectorProps )?.config.apiProvider as OpenAiProviderType; - setApiConfig({ - conversationId: conversation.id, - apiConfig: { - ...conversation.apiConfig, - connectorId, - provider: apiProvider, - }, - }); + onConnectorSelectionChange(connectorId, apiProvider); }, - [ - connectors, - conversation.apiConfig, - conversation.id, - setApiConfig, - onConnectorModalVisibilityChange, - ] + [connectors, onConnectorSelectionChange, onConnectorModalVisibilityChange] ); return ( <> {isConnectorModalVisible && ( { - setApiConfig({ - conversationId: conversation.id, - apiConfig: { - ...conversation.apiConfig, - connectorId: savedAction.id, - provider: (savedAction as ActionConnectorProps)?.config - .apiProvider as OpenAiProviderType, - }, - }); + onConnectorSelectionChange( + savedAction.id, + (savedAction as ActionConnectorProps)?.config + .apiProvider as OpenAiProviderType + ); refetchConnectors?.(); cleanupAndCloseModal(); }} diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_setup/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_setup/index.tsx index 063fc1961a2c0..e8a7940bca4d1 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_setup/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/connector_setup/index.tsx @@ -30,10 +30,8 @@ import * as i18n from '../translations'; import { useAssistantContext } from '../../assistant_context'; import { WELCOME_CONVERSATION_TITLE } from '../../assistant/use_conversation/translations'; -const MESSAGE_INDEX_BEFORE_CONNECTOR = 2; - const ConnectorButtonWrapper = styled.div` - margin-top: 20px; + margin-bottom: 10px; `; const SkipEuiText = styled(EuiText)` @@ -91,24 +89,40 @@ export const useConnectorSetup = ({ ); // User constants - const userName = conversation.theme?.user?.name ?? i18n.CONNECTOR_SETUP_USER_YOU; - const assistantName = conversation.theme?.assistant?.name ?? i18n.CONNECTOR_SETUP_USER_ASSISTANT; + const userName = useMemo( + () => conversation.theme?.user?.name ?? i18n.CONNECTOR_SETUP_USER_YOU, + [conversation.theme?.user?.name] + ); + const assistantName = useMemo( + () => conversation.theme?.assistant?.name ?? i18n.CONNECTOR_SETUP_USER_ASSISTANT, + [conversation.theme?.assistant?.name] + ); + const lastConversationMessageIndex = useMemo( + () => conversation.messages.length - 1, + [conversation.messages.length] + ); const [currentMessageIndex, setCurrentMessageIndex] = useState( // If connector is configured or conversation has already been replayed show all messages immediately isConnectorConfigured || conversationHasNoPresentationData(conversation) - ? MESSAGE_INDEX_BEFORE_CONNECTOR + ? lastConversationMessageIndex : 0 ); + const streamingTimeoutRef = useRef(undefined); + // Once streaming of previous message is complete, proceed to next message const onHandleMessageStreamingComplete = useCallback(() => { - const timeoutId = setTimeout(() => { + if (currentMessageIndex === lastConversationMessageIndex) { + clearTimeout(streamingTimeoutRef.current); + return; + } + streamingTimeoutRef.current = window.setTimeout(() => { bottomRef.current?.scrollIntoView({ block: 'end' }); return setCurrentMessageIndex(currentMessageIndex + 1); }, conversation.messages[currentMessageIndex]?.presentation?.delay ?? 0); - return () => clearTimeout(timeoutId); - }, [conversation.messages, currentMessageIndex]); + return () => clearTimeout(streamingTimeoutRef.current); + }, [conversation.messages, currentMessageIndex, lastConversationMessageIndex]); // Show button to add connector after last message has finished streaming const onHandleLastMessageStreamingComplete = useCallback(() => { @@ -120,8 +134,8 @@ export const useConnectorSetup = ({ // Show button to add connector after last message has finished streaming const handleSkipSetup = useCallback(() => { - setCurrentMessageIndex(MESSAGE_INDEX_BEFORE_CONNECTOR); - }, [setCurrentMessageIndex]); + setCurrentMessageIndex(lastConversationMessageIndex); + }, [lastConversationMessageIndex]); // Create EuiCommentProps[] from conversation messages const commentBody = useCallback( @@ -195,12 +209,9 @@ export const useConnectorSetup = ({ comments, prompt: (
- {(showAddConnectorButton || isConnectorConfigured) && ( + {showAddConnectorButton && ( - + )} {!showAddConnectorButton && ( diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/model_selector.tsx b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/model_selector.tsx new file mode 100644 index 0000000000000..bd585a6df1d61 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/model_selector.tsx @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo, useState } from 'react'; +import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; + +import * as i18n from './translations'; + +export const MODEL_GPT_3_5_TURBO = 'gpt-3.5-turbo'; +export const MODEL_GPT_4 = 'gpt-4'; +const DEFAULT_MODELS = [MODEL_GPT_3_5_TURBO, MODEL_GPT_4]; + +interface Props { + onModelSelectionChange?: (model?: string) => void; + models?: string[]; + selectedModel?: string; +} + +/** + * Selector for choosing and deleting models + * + * TODO: Pull from API once connector supports it `GET https://api.openai.com/v1/models` as models are added/deprecated + */ +export const ModelSelector: React.FC = React.memo( + ({ models = DEFAULT_MODELS, onModelSelectionChange, selectedModel = DEFAULT_MODELS[0] }) => { + // Form options + const [options, setOptions] = useState( + models.map((model) => ({ + label: model, + })) + ); + const selectedOptions = useMemo(() => { + return selectedModel ? [{ label: selectedModel }] : []; + }, [selectedModel]); + + const handleSelectionChange = useCallback( + (modelSelectorOption: EuiComboBoxOptionOption[]) => { + const newModel = + modelSelectorOption.length === 0 + ? undefined + : models.find((model) => model === modelSelectorOption[0]?.label) ?? + modelSelectorOption[0]?.label; + onModelSelectionChange?.(newModel); + }, + [onModelSelectionChange, models] + ); + + // Callback for when user types to create a new model + const onCreateOption = useCallback( + (searchValue, flattenedOptions = []) => { + if (!searchValue || !searchValue.trim().toLowerCase()) { + return; + } + + const normalizedSearchValue = searchValue.trim().toLowerCase(); + const optionExists = + flattenedOptions.findIndex( + (option: EuiComboBoxOptionOption) => + option.label.trim().toLowerCase() === normalizedSearchValue + ) !== -1; + + const newOption = { + value: searchValue, + label: searchValue, + }; + + if (!optionExists) { + setOptions([...options, newOption]); + } + handleSelectionChange([newOption]); + }, + [handleSelectionChange, options] + ); + + // Callback for when user selects a model + const onChange = useCallback( + (newOptions: EuiComboBoxOptionOption[]) => { + if (newOptions.length === 0) { + handleSelectionChange([]); + } else if (options.findIndex((o) => o.label === newOptions?.[0].label) !== -1) { + handleSelectionChange(newOptions); + } + }, + [handleSelectionChange, options] + ); + + return ( + + ); + } +); + +ModelSelector.displayName = 'ModelSelector'; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/translations.ts new file mode 100644 index 0000000000000..d379c8e142333 --- /dev/null +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/models/model_selector/translations.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const PLACEHOLDER_TEXT = i18n.translate( + 'xpack.elasticAssistant.connectors.models.modelSelector.placeholderText', + { + defaultMessage: 'Select or type to create new...', + } +); +export const MODEL_TITLE = i18n.translate( + 'xpack.elasticAssistant.connectors.models.modelSelector.modelTitle', + { + defaultMessage: 'Model', + } +); + +export const HELP_LABEL = i18n.translate( + 'xpack.elasticAssistant.connectors.models.modelSelector.helpLabel', + { + defaultMessage: 'Model to use for this connector', + } +); + +export const CUSTOM_OPTION_TEXT = i18n.translate( + 'xpack.elasticAssistant.connectors.models.modelSelector.customOptionText', + { + defaultMessage: 'Create new Model named', + } +); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/translations.ts index 923cb916df4e6..df6343f62b4e2 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/connectorland/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/connectorland/translations.ts @@ -100,3 +100,17 @@ export const CONNECTOR_SETUP_SKIP = i18n.translate( defaultMessage: 'Click to skip...', } ); + +export const MISSING_CONNECTOR_CALLOUT_TITLE = i18n.translate( + 'xpack.elasticAssistant.assistant.connectors.connectorMissingCallout.calloutTitle', + { + defaultMessage: 'The current conversation is missing a connector configuration', + } +); + +export const MISSING_CONNECTOR_CONVERSATION_SETTINGS_LINK = i18n.translate( + 'xpack.elasticAssistant.assistant.connectors.connectorMissingCallout.conversationSettingsLink', + { + defaultMessage: 'Conversation Settings', + } +); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/index.test.tsx index 583c0d8076a68..6bc8e93e3d5e2 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/index.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/index.test.tsx @@ -10,6 +10,15 @@ import { render, fireEvent } from '@testing-library/react'; import { TestProviders } from '../../../mock/test_providers/test_providers'; import { AnonymizationSettings } from '.'; +import type { Props } from '.'; + +const props: Props = { + defaultAllow: ['foo', 'bar', 'baz', '@baz'], + defaultAllowReplacement: ['bar'], + pageSize: 5, + setUpdatedDefaultAllow: jest.fn(), + setUpdatedDefaultAllowReplacement: jest.fn(), +}; const mockUseAssistantContext = { allSystemPrompts: [ @@ -47,14 +56,12 @@ jest.mock('../../../assistant_context', () => { }); describe('AnonymizationSettings', () => { - const closeModal = jest.fn(); - beforeEach(() => jest.clearAllMocks()); it('renders the editor', () => { const { getByTestId } = render( - + ); @@ -64,11 +71,11 @@ describe('AnonymizationSettings', () => { it('does NOT call `setDefaultAllow` when `Reset` is clicked, because only local state is reset until the user clicks save', () => { const { getByTestId } = render( - + ); - fireEvent.click(getByTestId('reset')); + fireEvent.click(getByTestId('resetFields')); expect(mockUseAssistantContext.setDefaultAllow).not.toHaveBeenCalled(); }); @@ -76,11 +83,11 @@ describe('AnonymizationSettings', () => { it('does NOT call `setDefaultAllowReplacement` when `Reset` is clicked, because only local state is reset until the user clicks save', () => { const { getByTestId } = render( - + ); - fireEvent.click(getByTestId('reset')); + fireEvent.click(getByTestId('resetFields')); expect(mockUseAssistantContext.setDefaultAllowReplacement).not.toHaveBeenCalled(); }); @@ -88,7 +95,7 @@ describe('AnonymizationSettings', () => { it('renders the expected allowed stat content', () => { const { getByTestId } = render( - + ); @@ -100,7 +107,7 @@ describe('AnonymizationSettings', () => { it('renders the expected anonymized stat content', () => { const { getByTestId } = render( - + ); @@ -108,52 +115,4 @@ describe('AnonymizationSettings', () => { `${mockUseAssistantContext.defaultAllowReplacement.length}Anonymized` ); }); - - it('calls closeModal is called when the cancel button is clicked', () => { - const { getByTestId } = render( - - - - ); - fireEvent.click(getByTestId('cancel')); - expect(closeModal).toHaveBeenCalledTimes(1); - }); - - it('calls closeModal is called when the save button is clicked', () => { - const { getByTestId } = render( - - - - ); - fireEvent.click(getByTestId('cancel')); - expect(closeModal).toHaveBeenCalledTimes(1); - }); - - it('calls setDefaultAllow with the expected values when the save button is clicked', () => { - const { getByTestId } = render( - - - - ); - - fireEvent.click(getByTestId('save')); - - expect(mockUseAssistantContext.setDefaultAllow).toHaveBeenCalledWith( - mockUseAssistantContext.defaultAllow - ); - }); - - it('calls setDefaultAllowReplacement with the expected values when the save button is clicked', () => { - const { getByTestId } = render( - - - - ); - - fireEvent.click(getByTestId('save')); - - expect(mockUseAssistantContext.setDefaultAllowReplacement).toHaveBeenCalledWith( - mockUseAssistantContext.defaultAllowReplacement - ); - }); }); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/index.tsx index e833276d4850d..31420e0452b1b 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/index.tsx @@ -6,14 +6,14 @@ */ import { - EuiButton, - EuiButtonEmpty, - EuiCallOut, EuiFlexGroup, EuiFlexItem, + EuiHorizontalRule, EuiSpacer, + EuiText, + EuiTitle, } from '@elastic/eui'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo } from 'react'; // eslint-disable-next-line @kbn/eslint/module_migration import styled from 'styled-components'; @@ -23,90 +23,71 @@ import type { BatchUpdateListItem } from '../../../data_anonymization_editor/con import { updateDefaults } from '../../../data_anonymization_editor/helpers'; import { AllowedStat } from '../../../data_anonymization_editor/stats/allowed_stat'; import { AnonymizedStat } from '../../../data_anonymization_editor/stats/anonymized_stat'; -import { CANCEL, SAVE } from '../anonymization_settings_modal/translations'; import * as i18n from './translations'; const StatFlexItem = styled(EuiFlexItem)` margin-right: ${({ theme }) => theme.eui.euiSizeL}; `; -interface Props { - closeModal?: () => void; +export interface Props { + defaultAllow: string[]; + defaultAllowReplacement: string[]; + pageSize?: number; + setUpdatedDefaultAllow: React.Dispatch>; + setUpdatedDefaultAllowReplacement: React.Dispatch>; } -const AnonymizationSettingsComponent: React.FC = ({ closeModal }) => { - const { - baseAllow, - baseAllowReplacement, - defaultAllow, - defaultAllowReplacement, - setDefaultAllow, - setDefaultAllowReplacement, - } = useAssistantContext(); - - // Local state for default allow and default allow replacement to allow for intermediate changes - const [localDefaultAllow, setLocalDefaultAllow] = useState(defaultAllow); - const [localDefaultAllowReplacement, setLocalDefaultAllowReplacement] = - useState(defaultAllowReplacement); +const AnonymizationSettingsComponent: React.FC = ({ + defaultAllow, + defaultAllowReplacement, + pageSize, + setUpdatedDefaultAllow, + setUpdatedDefaultAllowReplacement, +}) => { + const { baseAllow, baseAllowReplacement } = useAssistantContext(); const onListUpdated = useCallback( (updates: BatchUpdateListItem[]) => { updateDefaults({ - defaultAllow: localDefaultAllow, - defaultAllowReplacement: localDefaultAllowReplacement, - setDefaultAllow: setLocalDefaultAllow, - setDefaultAllowReplacement: setLocalDefaultAllowReplacement, + defaultAllow, + defaultAllowReplacement, + setDefaultAllow: setUpdatedDefaultAllow, + setDefaultAllowReplacement: setUpdatedDefaultAllowReplacement, updates, }); }, - [localDefaultAllow, localDefaultAllowReplacement] + [ + defaultAllow, + defaultAllowReplacement, + setUpdatedDefaultAllow, + setUpdatedDefaultAllowReplacement, + ] ); const onReset = useCallback(() => { - setLocalDefaultAllow(baseAllow); - setLocalDefaultAllowReplacement(baseAllowReplacement); - }, [baseAllow, baseAllowReplacement]); - - const onSave = useCallback(() => { - setDefaultAllow(localDefaultAllow); - setDefaultAllowReplacement(localDefaultAllowReplacement); - closeModal?.(); - }, [ - closeModal, - localDefaultAllow, - localDefaultAllowReplacement, - setDefaultAllow, - setDefaultAllowReplacement, - ]); + setUpdatedDefaultAllow(baseAllow); + setUpdatedDefaultAllowReplacement(baseAllowReplacement); + }, [baseAllow, baseAllowReplacement, setUpdatedDefaultAllow, setUpdatedDefaultAllowReplacement]); const anonymized: number = useMemo(() => { - const allowSet = new Set(localDefaultAllow); + const allowSet = new Set(defaultAllow); - return localDefaultAllowReplacement.reduce( - (acc, field) => (allowSet.has(field) ? acc + 1 : acc), - 0 - ); - }, [localDefaultAllow, localDefaultAllowReplacement]); + return defaultAllowReplacement.reduce((acc, field) => (allowSet.has(field) ? acc + 1 : acc), 0); + }, [defaultAllow, defaultAllowReplacement]); return ( <> - -

{i18n.CALLOUT_PARAGRAPH1}

- - {i18n.RESET} - -
- - + +

{i18n.SETTINGS_TITLE}

+
+ + {i18n.SETTINGS_DESCRIPTION} + + - + @@ -117,27 +98,13 @@ const AnonymizationSettingsComponent: React.FC = ({ closeModal }) => { - - - {closeModal != null && ( - - - {CANCEL} - - - )} - - - - {SAVE} - - - ); }; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/translations.ts index e7f82289dff78..82d0b7ec47701 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/translations.ts @@ -28,9 +28,16 @@ export const CALLOUT_TITLE = i18n.translate( } ); -export const RESET = i18n.translate( - 'xpack.elasticAssistant.dataAnonymization.settings.anonymizationSettings.resetButton', +export const SETTINGS_TITLE = i18n.translate( + 'xpack.elasticAssistant.dataAnonymization.settings.anonymizationSettings.settingsTitle', { - defaultMessage: 'Reset', + defaultMessage: 'Anonymization', + } +); +export const SETTINGS_DESCRIPTION = i18n.translate( + 'xpack.elasticAssistant.dataAnonymization.settings.anonymizationSettings.settingsDescription', + { + defaultMessage: + "When adding Prompt Context throughout the Security App that may contain sensitive information, you can choose which fields are sent, and whether to enable anonymization for these fields. This will replace the field's value with a random string before sending the conversation. Helpful defaults are provided below.", } ); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/index.test.tsx deleted file mode 100644 index 35ee1a1bde473..0000000000000 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/index.test.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { render, fireEvent, screen } from '@testing-library/react'; - -import { AnonymizationSettingsModal } from '.'; -import { TestProviders } from '../../../mock/test_providers/test_providers'; - -describe('AnonymizationSettingsModal', () => { - const closeModal = jest.fn(); - - beforeEach(() => { - jest.clearAllMocks(); - - render( - - - - ); - }); - - it('renders the anonymizationSettings', () => { - expect(screen.getByTestId('anonymizationSettingsCallout')).toBeInTheDocument(); - }); - - it('calls closeModal when Cancel is clicked', () => { - fireEvent.click(screen.getByTestId('cancel')); - - expect(closeModal).toHaveBeenCalledTimes(1); - }); - - it('calls closeModal when Save is clicked', () => { - fireEvent.click(screen.getByTestId('save')); - - expect(closeModal).toHaveBeenCalledTimes(1); - }); -}); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/index.tsx deleted file mode 100644 index ae4b395ca0d0e..0000000000000 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/index.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiModal, EuiModalBody, EuiModalHeader } from '@elastic/eui'; -import React from 'react'; - -import { AnonymizationSettings } from '../anonymization_settings'; - -interface Props { - closeModal: () => void; -} - -const AnonymizationSettingsModalComponent: React.FC = ({ closeModal }) => ( - - - - - - -); - -export const AnonymizationSettingsModal = React.memo(AnonymizationSettingsModalComponent); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/translations.ts deleted file mode 100644 index d3da99dcf5052..0000000000000 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_modal/translations.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const ANONYMIZATION = i18n.translate( - 'xpack.elasticAssistant.dataAnonymization.settings.anonymizationSettingsModal.anonymizationModalTitle', - { - defaultMessage: 'Anonymization', - } -); - -export const CANCEL = i18n.translate( - 'xpack.elasticAssistant.dataAnonymization.settings.anonymizationSettingsModal.cancelButton', - { - defaultMessage: 'Cancel', - } -); - -export const SAVE = i18n.translate( - 'xpack.elasticAssistant.dataAnonymization.settings.anonymizationSettingsModal.saveButton', - { - defaultMessage: 'Save', - } -); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/index.test.tsx deleted file mode 100644 index 3168c6a6b28dc..0000000000000 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/index.test.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; - -import { TestProviders } from '../../../mock/test_providers/test_providers'; -import * as i18n from './translations'; -import { SettingsPopover } from '.'; - -describe('SettingsPopover', () => { - beforeEach(() => { - render( - - - - ); - }); - - it('renders the settings button', () => { - const settingsButton = screen.getByTestId('settings'); - - expect(settingsButton).toBeInTheDocument(); - }); - - it('opens the popover when the settings button is clicked', () => { - const settingsButton = screen.getByTestId('settings'); - - userEvent.click(settingsButton); - - const popover = screen.queryByText(i18n.ANONYMIZATION); - expect(popover).toBeInTheDocument(); - }); -}); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/index.tsx deleted file mode 100644 index 634ccb5086178..0000000000000 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/index.tsx +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EuiButtonIcon, - EuiContextMenu, - EuiContextMenuPanelDescriptor, - EuiPopover, - useGeneratedHtmlId, -} from '@elastic/eui'; -import React, { useCallback, useMemo, useState } from 'react'; -import { AnonymizationSettingsModal } from '../anonymization_settings_modal'; - -import * as i18n from './translations'; - -const SettingsPopoverComponent: React.FC<{ isDisabled?: boolean }> = ({ isDisabled = false }) => { - const [showAnonymizationSettingsModal, setShowAnonymizationSettingsModal] = useState(false); - const closeAnonymizationSettingsModal = useCallback( - () => setShowAnonymizationSettingsModal(false), - [] - ); - - const contextMenuPopoverId = useGeneratedHtmlId(); - - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const closePopover = useCallback(() => setIsPopoverOpen(false), []); - - const onButtonClick = useCallback(() => setIsPopoverOpen((prev) => !prev), []); - const button = useMemo( - () => ( - - ), - [isDisabled, onButtonClick] - ); - - const panels: EuiContextMenuPanelDescriptor[] = useMemo( - () => [ - { - id: 0, - items: [ - { - icon: 'eyeClosed', - name: i18n.ANONYMIZATION, - onClick: () => { - closePopover(); - - setShowAnonymizationSettingsModal(true); - }, - }, - ], - size: 's', - width: 150, - }, - ], - [closePopover] - ); - - return ( - <> - - - - - {showAnonymizationSettingsModal && ( - - )} - - ); -}; - -SettingsPopoverComponent.displayName = 'SettingsPopoverComponent'; - -export const SettingsPopover = React.memo(SettingsPopoverComponent); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/translations.ts deleted file mode 100644 index 4fcbcfcfa596b..0000000000000 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/settings_popover/translations.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const ANONYMIZATION = i18n.translate( - 'xpack.elasticAssistant.dataAnonymization.settings.settingsPopover.anonymizationMenuItem', - { - defaultMessage: 'Anonymization', - } -); - -export const SETTINGS = i18n.translate( - 'xpack.elasticAssistant.dataAnonymization.settings.settingsPopover.settingsAriaLabel', - { - defaultMessage: 'Settings', - } -); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/index.tsx index 1aab52a0d6432..5e9e0b960f577 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/index.tsx @@ -17,11 +17,6 @@ import { BatchUpdateListItem, ContextEditorRow, FIELDS, SortConfig } from './typ export const DEFAULT_PAGE_SIZE = 10; -const pagination = { - initialPageSize: DEFAULT_PAGE_SIZE, - pageSizeOptions: [5, DEFAULT_PAGE_SIZE, 25, 50], -}; - const defaultSort: SortConfig = { sort: { direction: 'desc', @@ -33,7 +28,9 @@ export interface Props { allow: string[]; allowReplacement: string[]; onListUpdated: (updates: BatchUpdateListItem[]) => void; + onReset?: () => void; rawData: Record | null; + pageSize?: number; } const search: EuiSearchBarProps = { @@ -58,7 +55,9 @@ const ContextEditorComponent: React.FC = ({ allow, allowReplacement, onListUpdated, + onReset, rawData, + pageSize = DEFAULT_PAGE_SIZE, }) => { const [selected, setSelection] = useState([]); const selectionValue: EuiTableSelectionType = useMemo( @@ -89,17 +88,25 @@ const ContextEditorComponent: React.FC = ({ setTimeout(() => setSelection(rows), 0); // updates selection in the component state }, [rows]); + const pagination = useMemo(() => { + return { + initialPageSize: pageSize, + pageSizeOptions: [5, DEFAULT_PAGE_SIZE, 25, 50], + }; + }, [pageSize]); + const toolbar = useMemo( () => ( ), - [onListUpdated, onSelectAll, rawData, rows.length, selected] + [onListUpdated, onReset, onSelectAll, rawData, rows.length, selected] ); return ( diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/toolbar/index.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/toolbar/index.test.tsx index 11b2488c096ad..fc2fce0cf1bed 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/toolbar/index.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/toolbar/index.test.tsx @@ -40,6 +40,7 @@ describe('Toolbar', () => { const defaultProps = { onListUpdated: jest.fn(), onlyDefaults: false, + onReset: jest.fn(), onSelectAll: jest.fn(), selected: [], // no rows selected totalFields: 5, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/toolbar/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/toolbar/index.tsx index 476005c8da5ba..5a1568693e6f3 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/toolbar/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/toolbar/index.tsx @@ -15,6 +15,7 @@ import { BatchUpdateListItem, ContextEditorRow } from '../types'; export interface Props { onListUpdated: (updates: BatchUpdateListItem[]) => void; onlyDefaults: boolean; + onReset?: () => void; onSelectAll: () => void; selected: ContextEditorRow[]; totalFields: number; @@ -23,6 +24,7 @@ export interface Props { const ToolbarComponent: React.FC = ({ onListUpdated, onlyDefaults, + onReset, onSelectAll, selected, totalFields, @@ -54,6 +56,28 @@ const ToolbarComponent: React.FC = ({ selected={selected} /> + + {onReset != null && ( + + + + + {i18n.RESET} + + + + + )} ); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/translations.ts b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/translations.ts index a48a52ee8092a..7aeb655a5b343 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/translations.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization_editor/context_editor/translations.ts @@ -116,6 +116,12 @@ export const SELECTED_FIELDS = (selected: number) => values: { selected }, defaultMessage: 'Selected {selected} fields', }); +export const RESET = i18n.translate( + 'xpack.elasticAssistant.assistant.dataAnonymizationEditor.contextEditor.resetButton', + { + defaultMessage: 'Reset', + } +); export const UNANONYMIZE = i18n.translate( 'xpack.elasticAssistant.assistant.dataAnonymizationEditor.contextEditor.unanonymizeAction', diff --git a/x-pack/plugins/security_solution/public/assistant/content/prompts/system/translations.ts b/x-pack/plugins/security_solution/public/assistant/content/prompts/system/translations.ts index 660b71c857e8f..90c75a7405526 100644 --- a/x-pack/plugins/security_solution/public/assistant/content/prompts/system/translations.ts +++ b/x-pack/plugins/security_solution/public/assistant/content/prompts/system/translations.ts @@ -41,7 +41,7 @@ export const FORMAT_OUTPUT_CORRECTLY = i18n.translate( 'xpack.securitySolution.assistant.content.prompts.system.outputFormatting', { defaultMessage: - 'If you answer a question related to KQL or EQL, it should be immediately usable within an Elastic Security timeline, please always format the output correctly with back ticks. Any answer provided for Query DSL should also be usable in a security timeline. This means you should only ever include the "filter" portion of the query.', + 'If you answer a question related to KQL or EQL, it should be immediately usable within an Elastic Security timeline; please always format the output correctly with back ticks. Any answer provided for Query DSL should also be usable in a security timeline. This means you should only ever include the "filter" portion of the query.', } ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/translations.ts b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/translations.ts index 73baeb60ce4f4..f8daba8330a43 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/translations.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/tabs_content/translations.ts @@ -25,13 +25,6 @@ export const ANALYZER_TAB = i18n.translate( } ); -export const ASSISTANT_TAB = i18n.translate( - 'xpack.securitySolution.timeline.tabs.assistantTabTitle', - { - defaultMessage: 'Security assistant', - } -); - export const NOTES_TAB = i18n.translate( 'xpack.securitySolution.timeline.tabs.notesTabTimelineTitle', { @@ -49,7 +42,7 @@ export const PINNED_TAB = i18n.translate( export const SECURITY_ASSISTANT = i18n.translate( 'xpack.securitySolution.timeline.tabs.securityAssistantTimelineTitle', { - defaultMessage: 'Security Assistant', + defaultMessage: 'Elastic AI Assistant', } ); From 2e2da698570e9d0836c772c243ba243f138bd1f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jul 2023 09:51:50 +0200 Subject: [PATCH 55/97] Update dependency react-hook-form to ^7.44.2 (main) (#152895) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [react-hook-form](https://www.react-hook-form.com) ([source](https://togithub.com/react-hook-form/react-hook-form)) | [`^7.43.2` -> `^7.44.2`](https://renovatebot.com/diffs/npm/react-hook-form/7.43.2/7.44.2) | [![age](https://badges.renovateapi.com/packages/npm/react-hook-form/7.44.2/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/react-hook-form/7.44.2/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/react-hook-form/7.44.2/compatibility-slim/7.43.2)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/react-hook-form/7.44.2/confidence-slim/7.43.2)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
react-hook-form/react-hook-form ### [`v7.44.2`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.44.2): Version 7.44.2 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.44.1...v7.44.2) 🪟 fix [#​10456](https://togithub.com/react-hook-form/react-hook-form/issues/10456) `object.hasown` replaced with `hasOwnProperty` ([#​10458](https://togithub.com/react-hook-form/react-hook-form/issues/10458)) ### [`v7.44.1`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.44.1): Version 7.44.1 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.44.0...v7.44.1) 🐞 fix `` component content-type json type missing ([#​10454](https://togithub.com/react-hook-form/react-hook-form/issues/10454)) ### [`v7.44.0`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.44.0): Version 7.44.0 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.43.9...v7.44.0) 📄 New `` Component ([https://github.com/react-hook-form/react-hook-form/pull/9735](https://togithub.com/react-hook-form/react-hook-form/pull/9735)) https://react-hook-form.com/docs/useform/form - add try and catch for JSON.stringify ```tsx // Send post request with formData { alert("Great"); }} /> // Send post request with json form data {errors.root?.server.type === 500 && 'Error message'} {errors.root?.server.type === 400 && 'Error message'} // Send post request with formData with fetch
{ await fetch("api", { method: "post", body: formData, }); }} /> ``` 🗝️ support TransformedValues with useFormContext ([https://github.com/react-hook-form/react-hook-form/pull/10322](https://togithub.com/react-hook-form/react-hook-form/pull/10322)) ```tsx useFormContext() ``` 🚔 added TTransformedValues to FormProvider ([https://github.com/react-hook-form/react-hook-form/pull/10368](https://togithub.com/react-hook-form/react-hook-form/pull/10368)) ```tsx FormProviderProps ``` 🐞 fix [https://github.com/react-hook-form/react-hook-form/issues/10139](https://togithub.com/react-hook-form/react-hook-form/issues/10139) with errors diff from the previous with field array action ([https://github.com/react-hook-form/react-hook-form/pull/10216](https://togithub.com/react-hook-form/react-hook-form/pull/10216)) 🐞 related [https://github.com/react-hook-form/react-hook-form/issues/10238](https://togithub.com/react-hook-form/react-hook-form/issues/10238) return default values in watch and useWatch when reset is called with an empty object 🦮 remove unnecessary as unknown as cast ([https://github.com/react-hook-form/react-hook-form/pull/10300](https://togithub.com/react-hook-form/react-hook-form/pull/10300)) 🧛‍♂️ close [https://github.com/react-hook-form/react-hook-form/issues/10277](https://togithub.com/react-hook-form/react-hook-form/issues/10277) remove pattern empty string check ([https://github.com/react-hook-form/react-hook-form/pull/10279](https://togithub.com/react-hook-form/react-hook-form/pull/10279)) 🐞 fix [https://github.com/react-hook-form/react-hook-form/issues/9037](https://togithub.com/react-hook-form/react-hook-form/issues/9037) bugs that occur in the presence of Array polyfills ([https://github.com/react-hook-form/react-hook-form/pull/10328](https://togithub.com/react-hook-form/react-hook-form/pull/10328)) 🫥 close [https://github.com/react-hook-form/react-hook-form/issues/10348](https://togithub.com/react-hook-form/react-hook-form/issues/10348) stop shouldUseNativeValidation pass down constraint props ([https://github.com/react-hook-form/react-hook-form/pull/10350](https://togithub.com/react-hook-form/react-hook-form/pull/10350)) 😵‍💫 close [https://github.com/react-hook-form/react-hook-form/issues/10386](https://togithub.com/react-hook-form/react-hook-form/issues/10386) re-register controller input to fix strict mode ([https://github.com/react-hook-form/react-hook-form/pull/10418](https://togithub.com/react-hook-form/react-hook-form/pull/10418)) ✍️ update form.tsx for TSdoc ([https://github.com/react-hook-form/react-hook-form/pull/10399](https://togithub.com/react-hook-form/react-hook-form/pull/10399)) thanks to [@​yasamoka](https://togithub.com/yasamoka) & [@​Torvin](https://togithub.com/Torvin) [@​ryota-murakami](https://togithub.com/ryota-murakami) & [@​devakrishna33](https://togithub.com/devakrishna33) ### [`v7.43.9`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.43.9): Version 7.43.9 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.43.8...v7.43.9) 🍄 close [#​10195](https://togithub.com/react-hook-form/react-hook-form/issues/10195) close async defaultValues not load ([#​10203](https://togithub.com/react-hook-form/react-hook-form/issues/10203)) Revert "🐞 fix [#​10139](https://togithub.com/react-hook-form/react-hook-form/issues/10139) useFieldArray array error not updating in some cases ([#​10150](https://togithub.com/react-hook-form/react-hook-form/issues/10150))" ### [`v7.43.8`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.43.8): Version 7.43.8 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.43.7...v7.43.8) 🪡 related [#​10143](https://togithub.com/react-hook-form/react-hook-form/issues/10143) did not update dirty until interacted ([#​10157](https://togithub.com/react-hook-form/react-hook-form/issues/10157)) 🐞 fix [#​10139](https://togithub.com/react-hook-form/react-hook-form/issues/10139) useFieldArray array error not updating in some cases ([#​10150](https://togithub.com/react-hook-form/react-hook-form/issues/10150)) thanks to [@​kylemclean](https://togithub.com/kylemclean) ### [`v7.43.7`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.43.7): Version 7.43.7 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.43.6...v7.43.7) 🐞 fix [#​10131](https://togithub.com/react-hook-form/react-hook-form/issues/10131) regression on NaN data type ([#​10132](https://togithub.com/react-hook-form/react-hook-form/issues/10132)) 🐞 fix [#​10129](https://togithub.com/react-hook-form/react-hook-form/issues/10129) useFieldArray unmount fieldArray wihtout register ([#​10130](https://togithub.com/react-hook-form/react-hook-form/issues/10130)) 🦶 upgrade to TS 5.0.0 ([#​9834](https://togithub.com/react-hook-form/react-hook-form/issues/9834)) ### [`v7.43.6`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.43.6): Version 7.43.6 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.43.5...v7.43.6) 🐞 fix(appendErrors): incorrect type, it can take an array of errors ([#​10125](https://togithub.com/react-hook-form/react-hook-form/issues/10125)) ✍️ close [#​10096](https://togithub.com/react-hook-form/react-hook-form/issues/10096) react strict mode with mounted field value ([#​10102](https://togithub.com/react-hook-form/react-hook-form/issues/10102)) 🦮 fix: isLoading form state ([#​10095](https://togithub.com/react-hook-form/react-hook-form/issues/10095)) 📝 fix: typos in tsdoc ([#​10088](https://togithub.com/react-hook-form/react-hook-form/issues/10088)) 🩴 close [#​10078](https://togithub.com/react-hook-form/react-hook-form/issues/10078) prevent stabled aysnc validation ([#​10082](https://togithub.com/react-hook-form/react-hook-form/issues/10082)) 🐞 fix [#​10064](https://togithub.com/react-hook-form/react-hook-form/issues/10064) native validation when subscribe to isValid ([#​10072](https://togithub.com/react-hook-form/react-hook-form/issues/10072)) 📝 correct typo in field array type declaration ([#​10066](https://togithub.com/react-hook-form/react-hook-form/issues/10066)) thanks to [@​jorisre](https://togithub.com/jorisre) [@​chrisbarless](https://togithub.com/chrisbarless) [@​mjw-isp](https://togithub.com/mjw-isp) and [@​adamtowle](https://togithub.com/adamtowle) ### [`v7.43.5`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.43.5): Version 7.43.5 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.43.4...v7.43.5) 🐰 prevent runtime error with subscribe function ([#​10052](https://togithub.com/react-hook-form/react-hook-form/issues/10052)) 🪔 close [#​10045](https://togithub.com/react-hook-form/react-hook-form/issues/10045) improve `useController` defaultValue restore under strict mode with double `useEffect` ([#​10049](https://togithub.com/react-hook-form/react-hook-form/issues/10049)) 📷 improve form values state update ([#​10029](https://togithub.com/react-hook-form/react-hook-form/issues/10029)) ### [`v7.43.4`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.43.4): Version 7.43.4 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.43.3...v7.43.4) 🐞 fix [#​10021](https://togithub.com/react-hook-form/react-hook-form/issues/10021) issue with `.next` runtime error and fix cypress action ([#​10026](https://togithub.com/react-hook-form/react-hook-form/issues/10026)) ### [`v7.43.3`](https://togithub.com/react-hook-form/react-hook-form/releases/tag/v7.43.3): Version 7.43.3 [Compare Source](https://togithub.com/react-hook-form/react-hook-form/compare/v7.43.2...v7.43.3) 📐 fix `resetField` defaultValue type and reduce any type ([#​10024](https://togithub.com/react-hook-form/react-hook-form/issues/10024)) 🐞 fix [#​9997](https://togithub.com/react-hook-form/react-hook-form/issues/9997) issue on the mounted state is updated with values prop ([#​10001](https://togithub.com/react-hook-form/react-hook-form/issues/10001)) Revert "🏍 delete dirty fields node instead of marking as false ([#​9156](https://togithub.com/react-hook-form/react-hook-form/issues/9156))" ([#​9996](https://togithub.com/react-hook-form/react-hook-form/issues/9996)) 💅 improve state subscription consistency ([#​9984](https://togithub.com/react-hook-form/react-hook-form/issues/9984))
--- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/elastic/kibana). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Patryk Kopyciński --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 173d45abad247..559f93a4d5360 100644 --- a/package.json +++ b/package.json @@ -931,7 +931,7 @@ "react-fast-compare": "^2.0.4", "react-focus-on": "^3.7.0", "react-grid-layout": "^1.3.4", - "react-hook-form": "^7.43.2", + "react-hook-form": "^7.44.2", "react-intl": "^2.8.0", "react-is": "^17.0.2", "react-markdown": "^6.0.3", diff --git a/yarn.lock b/yarn.lock index ce26e20144928..0a81b7d2e5caf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24474,10 +24474,10 @@ react-grid-layout@^1.3.4: react-draggable "^4.0.0" react-resizable "^3.0.4" -react-hook-form@^7.43.2: - version "7.43.2" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.43.2.tgz#d8ff71956dc3de258dce19d4b1c7e1c6a0188e67" - integrity sha512-NvD3Oe2Y9hhqo2R4I4iJigDzSLpdMnzUpNMxlnzTbdiT7NT3BW0GxWCzEtwPudZMUPbZhNcSy1EcGAygyhDORg== +react-hook-form@^7.44.2: + version "7.44.3" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.44.3.tgz#a99e560c6ef2b668db1daaebc4f98267331b6828" + integrity sha512-/tHId6p2ViAka1wECMw8FEPn/oz/w226zehHrJyQ1oIzCBNMIJCaj6ZkQcv+MjDxYh9MWR7RQic7Qqwe4a5nkw== react-input-autosize@^3.0.0: version "3.0.0" From 9a7cc5a1d1fceed933c3714037d81c7ba067ea97 Mon Sep 17 00:00:00 2001 From: Mario Rodriguez Molins Date: Wed, 12 Jul 2023 09:53:41 +0200 Subject: [PATCH 56/97] [Fleet] Add support for Runtime Fields (#161129) ## Summary Closes https://github.com/elastic/kibana/issues/155255 Closes https://github.com/elastic/package-spec/issues/39 Add support in Fleet for Runtime fields, based on these docs: - Defining runtime fields: - https://www.elastic.co/guide/en/elasticsearch/reference/8.8/runtime-mapping-fields.html - https://www.elastic.co/guide/en/elasticsearch/reference/8.8/runtime-retrieving-fields.html - Mapping runtime fields in dynamic templates: - https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-templates.html#dynamic-mapping-runtime-fields - Adding runtime fields under groups Given these field definitions in packages: ```yaml - name: bar type: boolean - name: uptime type: keyword - name: runtime_boolean type: boolean runtime: true - name: runtime.day type: keyword runtime: >- emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)) - name: to_be_long type: long runtime: true - name: runtime.date type: date date_format: 'yyyy-MM-dd' runtime: >- emit(doc['@timestamp'].value.toEpochMilli()) - name: runtime.epoch_milli type: long runtime: >- emit(doc['@timestamp'].value.toEpochMilli()) - name: lowercase type: keyword runtime: >- emit(doc['uppercase'].value.toLowerCase()) - name: labels.* type: long object_type_mapping_type: double runtime: true - name: responses type: group fields: - name: runtime_group_boolean type: boolean runtime: true - name: foo type: boolean ``` and this definition in the manifest ```yaml elasticsearch: index_template: mappings: runtime: day_of_week_two: type: keyword script: source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" ``` This PR adds the required fields into the `mappings` key when installing the package. For this example, the resulting mappings are (just showing the relevant data for these changes): ```json { ".ds-logs-runtime_fields.foo-default-2023.07.10-000001": { "mappings": { "dynamic_templates": [ { "labels.*": { "path_match": "labels.*", "match_mapping_type": "double", "runtime": { "type": "long" } } } ], "runtime": { "day_of_week_two": { "type": "keyword", "script": { "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", "lang": "painless" } }, "labels.a": { "type": "long" }, "labels.b": { "type": "long" }, "lowercase": { "type": "keyword", "script": { "source": "emit(doc['uppercase'].value.toLowerCase())", "lang": "painless" } }, "responses.runtime_group_boolean": { "type": "boolean" }, "runtime.date": { "type": "date", "script": { "source": "emit(doc['@timestamp'].value.toEpochMilli())", "lang": "painless" }, "format": "yyyy-MM-dd" }, "runtime.day": { "type": "keyword", "script": { "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", "lang": "painless" } }, "runtime.epoch_milli": { "type": "long", "script": { "source": "emit(doc['@timestamp'].value.toEpochMilli())", "lang": "painless" } }, "runtime_boolean": { "type": "boolean" }, "to_be_long": { "type": "long" } }, "properties": { "@timestamp": { "type": "date", "ignore_malformed": false }, "bar": { "type": "boolean" }, "data_stream": { "properties": { "dataset": { "type": "constant_keyword" }, "namespace": { "type": "constant_keyword" }, "type": { "type": "constant_keyword" } } }, "labels": { "type": "object" }, "message": { "type": "keyword", "ignore_above": 1024 }, "responses": { "properties": { "foo": { "type": "boolean" } } }, "uppercase": { "type": "keyword", "ignore_above": 1024 }, "user": { "properties": { "id": { "type": "keyword", "ignore_above": 1024 } } } } } } } ``` Tested manually installing a package containing runtime field definitions as the example above. Tested also indexing some documents and retrieving the runtime fields: - Indexing documents: ```json POST /logs-runtime_fields.foo-default/_doc/ { "@timestamp": "2023-07-07T13:32:09.000Z", "datastream": { "dataset": "logs-runtime_fields.foo", "namespace": "default", "type": "logs" }, "user": { "id": "8a4f500d" }, "message": "Login successful", "labels": { "a": 1.6, "b": 2.5 }, "uppercase": "SOMETHING", "to_be_long": 1.6, "runtime_boolean": true, "responses.runtime_group_boolean": false } ``` - Retrieving runtime fields (`_source` disabled): ```json GET logs-runtime_fields.foo-default/_search { "fields": [ "@timestamp", "runtime_boolean", "responses.runtime_group_boolean", "runtime.day", "runtime.date", "runtime.epoch_milli", "labels.*", "uppercase", "lowercase", "to_be_long" ], "_source": false } ``` - Output: ```json ... "hits": [ { "_index": ".ds-logs-runtime_fields.foo-default-2023.07.10-000001", "_id": "_7p1P4kBtEvrlGnsxiFN", "_score": 1, "fields": { "uppercase": [ "SOMETHING" ], "runtime.date": [ "2023-07-10" ], "@timestamp": [ "2023-07-10T09:33:09.000Z" ], "lowercase": [ "something" ], "to_be_long": [ 1 ], "runtime_boolean": [ true ], "runtime.day": [ "Monday" ], "labels.a": [ 1 ], "labels.b": [ 2 ], "responses.runtime_group_boolean": [ false ], "runtime.epoch_milli": [ 1688981589000 ] } } ] ... ``` ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios (https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/fleet/common/types/models/epm.ts | 1 + .../elasticsearch/template/install.test.ts | 55 +++++++- .../epm/elasticsearch/template/install.ts | 7 +- .../elasticsearch/template/template.test.ts | 101 +++++++++++++++ .../epm/elasticsearch/template/template.ts | 107 ++++++++++++++-- .../fleet/server/services/epm/fields/field.ts | 1 + .../fleet_api_integration/apis/epm/index.js | 1 + .../apis/epm/install_runtime_field.ts | 118 ++++++++++++++++++ .../runtime_fields/0.0.1/LICENSE.txt | 93 ++++++++++++++ .../runtime_fields/0.0.1/changelog.yml | 6 + .../foo/agent/stream/stream.yml.hbs | 7 ++ .../elasticsearch/ingest_pipeline/default.yml | 13 ++ .../data_stream/foo/fields/base-fields.yml | 12 ++ .../0.0.1/data_stream/foo/fields/fields.yml | 39 ++++++ .../0.0.1/data_stream/foo/manifest.yml | 21 ++++ .../runtime_fields/0.0.1/docs/README.md | 84 +++++++++++++ .../runtime_fields/0.0.1/img/sample-logo.svg | 1 + .../0.0.1/img/sample-screenshot.png | Bin 0 -> 18849 bytes .../runtime_fields/0.0.1/manifest.yml | 33 +++++ 19 files changed, 689 insertions(+), 11 deletions(-) create mode 100644 x-pack/test/fleet_api_integration/apis/epm/install_runtime_field.ts create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/LICENSE.txt create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/changelog.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/agent/stream/stream.yml.hbs create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/elasticsearch/ingest_pipeline/default.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/fields/base-fields.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/fields/fields.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/manifest.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/docs/README.md create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/img/sample-logo.svg create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/img/sample-screenshot.png create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/manifest.yml diff --git a/x-pack/plugins/fleet/common/types/models/epm.ts b/x-pack/plugins/fleet/common/types/models/epm.ts index 759fa02229ef0..ec9f7f3d2fd42 100644 --- a/x-pack/plugins/fleet/common/types/models/epm.ts +++ b/x-pack/plugins/fleet/common/types/models/epm.ts @@ -582,6 +582,7 @@ export interface PackageAssetReference { export interface IndexTemplateMappings { properties: any; dynamic_templates?: any; + runtime?: any; } // This is an index template v2, see https://github.com/elastic/elasticsearch/issues/53101 diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.test.ts index fbb289a984eb0..2b185e2810492 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.test.ts @@ -320,11 +320,64 @@ describe('EPM index template install', () => { const packageTemplate = componentTemplates['logs-package.dataset@package'].template; if (!('settings' in packageTemplate)) { - throw new Error('no mappings on package template'); + throw new Error('no settings on package template'); } expect(packageTemplate.settings?.index?.mapping).toEqual( expect.objectContaining({ ignored_malformed: true }) ); }); + + it('test prepareTemplate to set a runtime field in index_template.mappings', () => { + const dataStream = { + type: 'logs', + dataset: 'package.dataset', + title: 'test data stream', + release: 'experimental', + package: 'package', + path: 'path', + ingest_pipeline: 'default', + elasticsearch: { + 'index_template.mappings': { + runtime: { + day_of_week: { + type: 'keyword', + script: { + source: + "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", + }, + }, + }, + }, + }, + } as RegistryDataStream; + + const pkg = { + name: 'package', + version: '0.0.1', + }; + + const { componentTemplates } = prepareTemplate({ + pkg, + dataStream, + }); + + const packageTemplate = componentTemplates['logs-package.dataset@package'].template; + + if (!('mappings' in packageTemplate)) { + throw new Error('no mappings on package template'); + } + + expect(packageTemplate.mappings?.runtime).toEqual( + expect.objectContaining({ + day_of_week: { + type: 'keyword', + script: { + source: + "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", + }, + }, + }) + ); + }); }); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts index 1780d3e55169a..b20499daeec5c 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts @@ -332,6 +332,8 @@ export function buildComponentTemplates(params: { (dynampingTemplate) => Object.keys(dynampingTemplate)[0] ); + const mappingsRuntimeFields = merge(mappings.runtime, indexTemplateMappings.runtime ?? {}); + const isTimeSeriesEnabledByDefault = registryElasticsearch?.index_mode === 'time_series'; const isSyntheticSourceEnabledByDefault = registryElasticsearch?.source_mode === 'synthetic'; @@ -359,8 +361,11 @@ export function buildComponentTemplates(params: { }, mappings: { properties: mappingsProperties, + ...(Object.keys(mappingsRuntimeFields).length > 0 + ? { runtime: mappingsRuntimeFields } + : {}), dynamic_templates: mappingsDynamicTemplates.length ? mappingsDynamicTemplates : undefined, - ...omit(indexTemplateMappings, 'properties', 'dynamic_templates', '_source'), + ...omit(indexTemplateMappings, 'properties', 'dynamic_templates', '_source', 'runtime'), ...(indexTemplateMappings?._source || sourceModeSynthetic ? { _source: { diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts index e42106afda2c2..707727f558697 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts @@ -1021,6 +1021,107 @@ describe('EPM template', () => { expect(JSON.stringify(mappings)).toEqual(JSON.stringify(fieldMapping)); }); + it('tests processing runtime fields without script', () => { + const textWithRuntimeFieldsLiteralYml = ` +- name: runtime_field + type: boolean + runtime: true +`; + const runtimeFieldMapping = { + properties: {}, + runtime: { + runtime_field: { + type: 'boolean', + }, + }, + }; + const fields: Field[] = safeLoad(textWithRuntimeFieldsLiteralYml); + const processedFields = processFields(fields); + const mappings = generateMappings(processedFields); + expect(mappings).toEqual(runtimeFieldMapping); + }); + + it('tests processing runtime fields with painless script', () => { + const textWithRuntimeFieldsLiteralYml = ` +- name: day_of_week + type: date + runtime: | + emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)) +`; + const runtimeFieldMapping = { + properties: {}, + runtime: { + day_of_week: { + type: 'date', + script: { + source: + "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", + }, + }, + }, + }; + const fields: Field[] = safeLoad(textWithRuntimeFieldsLiteralYml); + const processedFields = processFields(fields); + const mappings = generateMappings(processedFields); + expect(mappings).toEqual(runtimeFieldMapping); + }); + + it('tests processing runtime fields defined in a group', () => { + const textWithRuntimeFieldsLiteralYml = ` +- name: responses + type: group + fields: + - name: day_of_week + type: date + date_format: date_optional_time + runtime: | + emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)) +`; + const runtimeFieldMapping = { + properties: {}, + runtime: { + 'responses.day_of_week': { + type: 'date', + format: 'date_optional_time', + script: { + source: + "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", + }, + }, + }, + }; + const fields: Field[] = safeLoad(textWithRuntimeFieldsLiteralYml); + const processedFields = processFields(fields); + const mappings = generateMappings(processedFields); + expect(mappings).toEqual(runtimeFieldMapping); + }); + + it('tests processing runtime fields in a dynamic template', () => { + const textWithRuntimeFieldsLiteralYml = ` +- name: labels.* + type: keyword + runtime: true +`; + const runtimeFieldMapping = { + properties: {}, + dynamic_templates: [ + { + 'labels.*': { + match_mapping_type: 'string', + path_match: 'labels.*', + runtime: { + type: 'keyword', + }, + }, + }, + ], + }; + const fields: Field[] = safeLoad(textWithRuntimeFieldsLiteralYml); + const processedFields = processFields(fields); + const mappings = generateMappings(processedFields); + expect(mappings).toEqual(runtimeFieldMapping); + }); + it('tests priority and index pattern for data stream without dataset_is_prefix', () => { const dataStreamDatasetIsPrefixUnset = { type: 'metrics', diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts index 7aebf1ba7eb83..2592e41862b18 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts @@ -38,6 +38,10 @@ interface MultiFields { [key: string]: object; } +interface RuntimeFields { + [key: string]: any; +} + export interface IndexTemplateMapping { [key: string]: any; } @@ -115,6 +119,7 @@ export function getTemplate({ export function generateMappings(fields: Field[]): IndexTemplateMappings { const dynamicTemplates: Array> = []; const dynamicTemplateNames = new Set(); + const runtimeFields: RuntimeFields = {}; const { properties } = _generateMappings(fields, { addDynamicMapping: (dynamicMapping: { @@ -122,15 +127,19 @@ export function generateMappings(fields: Field[]): IndexTemplateMappings { matchingType: string; pathMatch: string; properties: string; + runtimeProperties?: string; }) => { const name = dynamicMapping.path; if (dynamicTemplateNames.has(name)) { return; } - const dynamicTemplate: Properties = { - mapping: dynamicMapping.properties, - }; + const dynamicTemplate: Properties = {}; + if (dynamicMapping.runtimeProperties !== undefined) { + dynamicTemplate.runtime = dynamicMapping.runtimeProperties; + } else { + dynamicTemplate.mapping = dynamicMapping.properties; + } if (dynamicMapping.matchingType) { dynamicTemplate.match_mapping_type = dynamicMapping.matchingType; @@ -139,17 +148,23 @@ export function generateMappings(fields: Field[]): IndexTemplateMappings { if (dynamicMapping.pathMatch) { dynamicTemplate.path_match = dynamicMapping.pathMatch; } + dynamicTemplateNames.add(name); dynamicTemplates.push({ [dynamicMapping.path]: dynamicTemplate }); }, + addRuntimeField: (runtimeField: { path: string; properties: Properties }) => { + runtimeFields[`${runtimeField.path}`] = runtimeField.properties; + }, }); - return dynamicTemplates.length - ? { - properties, - dynamic_templates: dynamicTemplates, - } - : { properties }; + const indexTemplateMappings: IndexTemplateMappings = { properties }; + if (dynamicTemplates.length > 0) { + indexTemplateMappings.dynamic_templates = dynamicTemplates; + } + if (Object.keys(runtimeFields).length > 0) { + indexTemplateMappings.runtime = runtimeFields; + } + return indexTemplateMappings; } /** @@ -164,6 +179,7 @@ function _generateMappings( fields: Field[], ctx: { addDynamicMapping: any; + addRuntimeField: any; groupFieldName?: string; } ): { @@ -179,6 +195,55 @@ function _generateMappings( // If type is not defined, assume keyword const type = field.type || 'keyword'; + if (field.runtime !== undefined) { + const path = ctx.groupFieldName ? `${ctx.groupFieldName}.${field.name}` : field.name; + let runtimeFieldProps: Properties = getDefaultProperties(field); + + // Is it a dynamic template? + if (type === 'object' && field.object_type) { + const pathMatch = path.includes('*') ? path : `${path}.*`; + + let dynProperties: Properties = getDefaultProperties(field); + let matchingType: string | undefined; + switch (field.object_type) { + case 'keyword': + dynProperties.type = field.object_type; + matchingType = field.object_type_mapping_type ?? 'string'; + break; + case 'double': + case 'long': + case 'boolean': + dynProperties = { + type: field.object_type, + time_series_metric: field.metric_type, + }; + matchingType = field.object_type_mapping_type ?? field.object_type; + default: + break; + } + + // get the runtime properies of this field assuming type equals to object_type + const _field = { ...field, type: field.object_type }; + const fieldProps = generateRuntimeFieldProps(_field); + + if (dynProperties && matchingType) { + ctx.addDynamicMapping({ + path, + pathMatch, + matchingType, + properties: dynProperties, + runtimeProperties: fieldProps, + }); + } + return; + } + const fieldProps = generateRuntimeFieldProps(field); + runtimeFieldProps = { ...runtimeFieldProps, ...fieldProps }; + + ctx.addRuntimeField({ path, properties: runtimeFieldProps }); + return; // runtime fields should not be added as a property + } + if (type === 'object' && field.object_type) { const path = ctx.groupFieldName ? `${ctx.groupFieldName}.${field.name}` : field.name; const pathMatch = path.includes('*') ? path : `${path}.*`; @@ -435,6 +500,30 @@ function generateDateMapping(field: Field): IndexTemplateMapping { return mapping; } +function generateRuntimeFieldProps(field: Field): IndexTemplateMapping { + let mapping: IndexTemplateMapping = {}; + const type = field.type || keyword; + switch (type) { + case 'integer': + mapping.type = 'long'; + break; + case 'date': + const dateMappings = generateDateMapping(field); + mapping = { ...mapping, ...dateMappings, type: 'date' }; + break; + default: + mapping.type = type; + } + + if (typeof field.runtime === 'string') { + const scriptObject = { + source: field.runtime.trim(), + }; + mapping.script = scriptObject; + } + return mapping; +} + /** * Generates the template name out of the given information */ diff --git a/x-pack/plugins/fleet/server/services/epm/fields/field.ts b/x-pack/plugins/fleet/server/services/epm/fields/field.ts index 893d1c678d86e..ee8af0d303a38 100644 --- a/x-pack/plugins/fleet/server/services/epm/fields/field.ts +++ b/x-pack/plugins/fleet/server/services/epm/fields/field.ts @@ -39,6 +39,7 @@ export interface Field { null_value?: string; dimension?: boolean; default_field?: boolean; + runtime?: boolean | string; // Fields specific of the aggregate_metric_double type metrics?: string[]; diff --git a/x-pack/test/fleet_api_integration/apis/epm/index.js b/x-pack/test/fleet_api_integration/apis/epm/index.js index 06caa68bbbe61..70b655a59424b 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/index.js +++ b/x-pack/test/fleet_api_integration/apis/epm/index.js @@ -43,5 +43,6 @@ export default function loadTests({ loadTestFile, getService }) { loadTestFile(require.resolve('./install_hidden_datastreams')); loadTestFile(require.resolve('./bulk_get_assets')); loadTestFile(require.resolve('./install_dynamic_template_metric')); + loadTestFile(require.resolve('./install_runtime_field')); }); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_runtime_field.ts b/x-pack/test/fleet_api_integration/apis/epm/install_runtime_field.ts new file mode 100644 index 0000000000000..76038063146e2 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/epm/install_runtime_field.ts @@ -0,0 +1,118 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +/* eslint-disable no-console */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { skipIfNoDockerRegistry } from '../../helpers'; +import { setupFleetAndAgents } from '../agents/services'; + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const supertest = getService('supertest'); + const dockerServers = getService('dockerServers'); + const es = getService('es'); + + const testPackage = 'runtime_fields'; + const testPackageVersion = '0.0.1'; + const server = dockerServers.get('registry'); + + const deletePackage = async (name: string, version: string) => { + await supertest.delete(`/api/fleet/epm/packages/${name}/${version}`).set('kbn-xsrf', 'xxxx'); + }; + + describe('package with runtime fields', async () => { + skipIfNoDockerRegistry(providerContext); + setupFleetAndAgents(providerContext); + + after(async () => { + if (server.enabled) { + await deletePackage(testPackage, testPackageVersion); + } + }); + + it('should install with runtime fields added in component template', async function () { + const templateName = 'logs-runtime_fields.foo@package'; + + await supertest + .post(`/api/fleet/epm/packages/${testPackage}/${testPackageVersion}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }) + .expect(200); + + const { body: resp } = await es.transport.request( + { + method: 'GET', + path: `/_component_template/${templateName}`, + }, + { meta: true } + ); + + const template = resp.component_templates[0].component_template; + const runtimeFieldDefinitions = template.template.mappings.runtime; + console.log(JSON.stringify(runtimeFieldDefinitions, null, 2)); + + expect(runtimeFieldDefinitions).to.eql({ + day_of_week_two: { + script: { + source: + "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", + }, + type: 'keyword', + }, + 'responses.runtime_group_boolean': { + type: 'boolean', + }, + 'runtime.date': { + format: 'yyyy-MM-dd', + script: { + source: "emit(doc['@timestamp'].value.toEpochMilli())", + }, + type: 'date', + }, + 'runtime.day': { + script: { + source: + "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))", + }, + type: 'keyword', + }, + 'runtime.epoch_milli': { + type: 'long', + script: { + source: "emit(doc['@timestamp'].value.toEpochMilli())", + }, + }, + runtime_boolean: { + type: 'boolean', + }, + to_be_long: { + type: 'long', + }, + lowercase: { + type: 'keyword', + script: { + source: "emit(doc['uppercase'].value.toLowerCase())", + }, + }, + }); + + const dynamicTemplates = template.template.mappings.dynamic_templates; + expect(dynamicTemplates).to.eql([ + { + 'labels.*': { + path_match: 'labels.*', + match_mapping_type: 'double', + runtime: { + type: 'long', + }, + }, + }, + ]); + }); + }); +} diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/LICENSE.txt b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/LICENSE.txt new file mode 100644 index 0000000000000..809108b857ffd --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/LICENSE.txt @@ -0,0 +1,93 @@ +Elastic License 2.0 + +URL: https://www.elastic.co/licensing/elastic-license + +## Acceptance + +By using the software, you agree to all of the terms and conditions below. + +## Copyright License + +The licensor grants you a non-exclusive, royalty-free, worldwide, +non-sublicensable, non-transferable license to use, copy, distribute, make +available, and prepare derivative works of the software, in each case subject to +the limitations and conditions below. + +## Limitations + +You may not provide the software to third parties as a hosted or managed +service, where the service provides users with access to any substantial set of +the features or functionality of the software. + +You may not move, change, disable, or circumvent the license key functionality +in the software, and you may not remove or obscure any functionality in the +software that is protected by the license key. + +You may not alter, remove, or obscure any licensing, copyright, or other notices +of the licensor in the software. Any use of the licensor’s trademarks is subject +to applicable law. + +## Patents + +The licensor grants you a license, under any patent claims the licensor can +license, or becomes able to license, to make, have made, use, sell, offer for +sale, import and have imported the software, in each case subject to the +limitations and conditions in this license. This license does not cover any +patent claims that you cause to be infringed by modifications or additions to +the software. If you or your company make any written claim that the software +infringes or contributes to infringement of any patent, your patent license for +the software granted under these terms ends immediately. If your company makes +such a claim, your patent license ends immediately for work on behalf of your +company. + +## Notices + +You must ensure that anyone who gets a copy of any part of the software from you +also gets a copy of these terms. + +If you modify the software, you must include in any modified copies of the +software prominent notices stating that you have modified the software. + +## No Other Rights + +These terms do not imply any licenses other than those expressly granted in +these terms. + +## Termination + +If you use the software in violation of these terms, such use is not licensed, +and your licenses will automatically terminate. If the licensor provides you +with a notice of your violation, and you cease all violation of this license no +later than 30 days after you receive that notice, your licenses will be +reinstated retroactively. However, if you violate these terms after such +reinstatement, any additional violation of these terms will cause your licenses +to terminate automatically and permanently. + +## No Liability + +*As far as the law allows, the software comes as is, without any warranty or +condition, and the licensor will not be liable to you for any damages arising +out of these terms or the use or nature of the software, under any kind of +legal claim.* + +## Definitions + +The **licensor** is the entity offering these terms, and the **software** is the +software the licensor makes available under these terms, including any portion +of it. + +**you** refers to the individual or entity agreeing to these terms. + +**your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control over, +are under the control of, or are under common control with that +organization. **control** means ownership of substantially all the assets of an +entity, or the power to direct its management and policies by vote, contract, or +otherwise. Control can be direct or indirect. + +**your licenses** are all the licenses granted to you for the software under +these terms. + +**use** means anything you do with the software requiring one of your licenses. + +**trademark** means trademarks, service marks, and similar rights. diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/changelog.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/changelog.yml new file mode 100644 index 0000000000000..bb0320a5243f7 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/changelog.yml @@ -0,0 +1,6 @@ +# newer versions go on top +- version: "0.0.1" + changes: + - description: Initial draft of the package + type: enhancement + link: https://github.com/elastic/integrations/pull/1 # FIXME Replace with the real PR link diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/agent/stream/stream.yml.hbs b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/agent/stream/stream.yml.hbs new file mode 100644 index 0000000000000..5845510de8091 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/agent/stream/stream.yml.hbs @@ -0,0 +1,7 @@ +paths: +{{#each paths as |path i|}} + - {{path}} +{{/each}} +exclude_files: [".gz$"] +processors: + - add_locale: ~ diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/elasticsearch/ingest_pipeline/default.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/elasticsearch/ingest_pipeline/default.yml new file mode 100644 index 0000000000000..133040687bbfd --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/elasticsearch/ingest_pipeline/default.yml @@ -0,0 +1,13 @@ +--- +description: Pipeline for processing sample logs +processors: +- set: + field: sample_field + value: "1" +- set: + field: my_date + copy_from: "@timestamp" +on_failure: +- set: + field: error.message + value: '{{ _ingest.on_failure_message }}' \ No newline at end of file diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/fields/base-fields.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/fields/base-fields.yml new file mode 100644 index 0000000000000..7c798f4534ca5 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/fields/base-fields.yml @@ -0,0 +1,12 @@ +- name: data_stream.type + type: constant_keyword + description: Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: Data stream namespace. +- name: '@timestamp' + type: date + description: Event timestamp. diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/fields/fields.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/fields/fields.yml new file mode 100644 index 0000000000000..43e2060dc2296 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/fields/fields.yml @@ -0,0 +1,39 @@ +- name: bar + type: boolean +- name: uppercase + type: keyword +- name: runtime_boolean + type: boolean + runtime: true +- name: to_be_long + type: long + runtime: true +- name: runtime.day + type: keyword + runtime: >- + emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)) +- name: lowercase + type: keyword + runtime: >- + emit(doc['uppercase'].value.toLowerCase()) +- name: runtime.date + type: date + date_format: 'yyyy-MM-dd' + runtime: >- + emit(doc['@timestamp'].value.toEpochMilli()) +- name: runtime.epoch_milli + type: long + runtime: >- + emit(doc['@timestamp'].value.toEpochMilli()) +- name: labels.* + type: long + object_type_mapping_type: double + runtime: true +- name: responses + type: group + fields: + - name: runtime_group_boolean + type: boolean + runtime: true + - name: foo + type: boolean diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/manifest.yml new file mode 100644 index 0000000000000..20c70816edc49 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/data_stream/foo/manifest.yml @@ -0,0 +1,21 @@ +title: "Foo" +type: logs +streams: + - input: logfile + title: Sample logs + description: Collect sample logs + vars: + - name: paths + type: text + title: Paths + multi: true + default: + - /var/log/*.log +elasticsearch: + index_template: + mappings: + runtime: + day_of_week_two: + type: keyword + script: + source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/docs/README.md b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/docs/README.md new file mode 100644 index 0000000000000..df19b78da8dd9 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/docs/README.md @@ -0,0 +1,84 @@ + + + +# Runtime fields + + + +## Data streams + + + + + + + + + + + +## Requirements + +You need Elasticsearch for storing and searching your data and Kibana for visualizing and managing it. +You can use our hosted Elasticsearch Service on Elastic Cloud, which is recommended, or self-manage the Elastic Stack on your own hardware. + + + +## Setup + + + +For step-by-step instructions on how to set up an integration, see the +[Getting started](https://www.elastic.co/guide/en/welcome-to-elastic/current/getting-started-observability.html) guide. + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/img/sample-logo.svg b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/img/sample-logo.svg new file mode 100644 index 0000000000000..6268dd88f3b3d --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/img/sample-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/img/sample-screenshot.png b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/img/sample-screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..d7a56a3ecc078c38636698cefba33f86291dd178 GIT binary patch literal 18849 zcmeEu^S~#!E#4Tq;}?6chqwB{?k=6jc5D4>l%v(rleJ2Y%tW zDj9g7px}|*e;{M?LDwiK3@FNS(lDRTd-MJYIyUJCN948~OJk1M(DrJyI#iV;P4k~& zFZo35IfQt0RwlUN`48^6(1dv_wm(y1xhEdMld=Y?!%u=fPT_*{3( zwBwz3#qR}_)t>C*jp5@U)Ti~B)Y;qq*TRxZJ7ZRN_^A3TDAEM*@7Ve%(Ro7=1%1B< zVj6GBUTxXev>_^SFA zgKZ=g4aTS}9>Ofj7cSB0WO?gQ)x=+!hs_)b$6#>ScFZ>XAoIX)%Bc|BDC~JFBk0f0 z0NY}6gb)&!qx^FWC(!ji+Kl$V$2|ocA=vN0TM0Y`U?tX+T)c*C zA!IL(T2Vm%MCLa85^if@J@Kkprx8QN5!6eCR@4Oa5S?4-4|ou?90mFCM8D!;n(5xz zO}-*t!TntN>|a$s(kGQg1P-U?hqvGF2_fGvd&~yZ_l3Qf&j~XWa=;>N3#-~#zjzcc z*m18L`A-K2o!d@J>a8SRbm4P&-q1(H>|JgIymDbnJF&@008`=X!P?4DGgZb>voUl^ zNJKgPR4S={)3vuk_{n@=M8q;;aJL>q+VLdTnO=}`&x;1DKjJA3*f*idS{jP5?+;!W zn-^7021Z4zv`Aq`hmX1aid997RNh3fa-@PG(W7TzKa1W&5^y3|lPeETP7j9qXpo4)7%(W0_2 z^Nmq;t@rb1eP3?%kOkH`P%!zTC7ZHjSfNN3*Sb#=3#jB*KpNGNfnRZ{N(6DrW(;B2Bwom<%m?VQP%K+ zsFeF1-(DY}oP@)w^Kw~gPg03q?N;)Ec6^|nikA34T~RynX*z}H>R~qgT$`Zbhn8wzZs$j2fsGN&rOK-mIBBvzD@a8FgbLpL!h5N^u&0wG} zq!#md3MHITv?3@$37J?lc_5*LWJTTjel;IiU-Yq;(g9I^D&KN_NKVS0O~GvB~FzPM6}=4d%fG4Nw4pZshcyLqK@`b8?RhD38haIyr@+8+0r5TC1*C7^WleJ zZN3_ngTD#RQvNL*;qD2H@cBWJbCC#d!}=oKfod5SE9a?!?j%DVt1z@inN}Iy$r+96 zM@P?AC+(`cM;z6J94BYGJ;+P-N#yj$?`G26ydS&OVH?~JY(N4l()Fh+x+DoJ@r<+i zhm^ck@QP`=fLApr62@KyOef~}zuG;(VbDQmw|Wb+oSHSw=%w9R)=et0cY*~ytX)#M zEXlK^p;zM@vTnXn+C1vwP)~TJv|TvDE2($;;EzC5_5IL#H;u z)#CO8)TSzbt8)wHB8$I8KcIojx&GoE)3QNu{CQ+_xBmQ&`mL5-u=BX(hs^hMY^ zae!!*Q;Tr$@(0~GoBJAohGw*d{l8~!aXop87aaSUb2jm)Tk>#$1*cdo5Sl+?oD!l4Og~yX+soottl4 zp4OartUuAN(dD~yLJ}`A1*!D4-|L^hM;`_DM^1KYs-VF(}h(BjRO``b+xV~%O=-)?p z7ciJH7Fnl?V&=ay_AB{oQoa2iR;6$^tiE|-eRCFy|3F@%j#6gUxkZX@?K`F$u#;T< z4IZORpUthmB?U`;zrOkp?P(Rvd5TFRWrBJmVg;KEZvJ+;Q}FRY%QZ?c^&$oPXW+C5 zdN#c>v%U?QuE+hMQdzxS1Q(BT90;29qu#^A?a^)Ui;{TJ;%`nLgm2ew$J4NvREjCJ z$`C7&?tH$CrVG@M3J1-KJw_*9BKeL*JX{ zN+Vg_TXb9^jJO$ZGkXO6BBFDjt~w5`w2TB*z$&1W5Il3IiDs=ZMDt|9iRtKET*wF6 z0Z+|N87p-5Fh)^(*l>OVr5^aY5LW(@PuM>Qo@&)yj6XRkPm1>eTF#Y_c*aRF^ZY5A z9FAU7lKEHG@i{wJMPg;n6z2|69d-)q9@<7t()d-zPy&X zdXG7{Uw{k23)CzzQAXw#iqj<1u~W@K_Ljc#?ukh;fRKHeJ2l~Z+52b2n^bGiDF2oX zm25FLx|4AP8>rAi@koY03lrtS#X?zK591c?2iZ_jjc>0y>q9>fU<08o6zG%z9WK+S zDwZMW4~28wu#ye#V*@#5t^S@NiAA`3{SF$xINmc_WW^u-C9M=H>RQ1>WM=|R!660{ z6E6%DwX`eu<3pkmz7Z=FCRd$(vhDkc3yMnSr)5C*aho)DZ<12$`$TXj<8Z70)|rK7 zXFD8QzksfWZU`qL2K8X{C~TcF{KVW`3Y{IMb&)T9%1V`tv(HY1 z+LXkLyM|3mtLD{x-#hOw-U?sr-iLeHFA|=-sGZ4#hX)atL!a91(tWJc+og&5W}VfZ zpgE7`{5D`~?yGR++y7~xA&eU0N*ZezDjF$> zUeK&1aTFQRg*?v^Z2e7u<`lk$czR6}b6Cl-qA9%A`#A6q0*zyTu)X`3rhjR86NK3= zLdw{+-F}+b2gxd-qF7>Rla}dFkj|L#c|pg5Ni+MRA|BZH(@ME*o<1ijKcoXb%PVfJ ztp_uf=G%kvU((pHcw90Xut=}atA!giM-5By)f40nKp zv7Wdb{;^<}VRvruH~rYr~wEuYY2ov-5Q|p@u3Da9+z7PeIpBAwi?RxnxN3Kt+N9L(LUS%wxY` z>e&1VV;{CYw8DNRlvBH)>!I49SU4R!t3I4=y;mCevPZh!-}~G+F>6hcL_Rli4r zC4(WN)`j$>^S=~GMGR=^)A6wrqi(-x{xK37&Vx!OS6t=KQ2JVZo#GrSODtTe=TVh%*qfF%91nqsMNLNL^Gp|_ zz%I*HUkMQGqb!1eh{{bp|0GSCDbkG_D_d)8<(0r<6-%Qi7qDa7xZjcdZ$?Rth9L!f z$erCcs3<~mtupywbaT8NWZF#v?iZkvqSz3@p`RiXs7P!GUa~-U9hEG(NgI#3BzO-# z!9JWf(;r!*A=@g$f}>wi|6Q@9z8AmYf~x8G%sp>C5cfuJY;hs1o3Ozu^{pH0AFbs%yU)Xy5>Cf?qXiHn*-PAfKDRiy`U0sFSKFsgEZ6_ z9#ma!<#Izr^}_z*>PRSt564u6We*XmZUx^jv*dK; z4zyFZ*ZFSE!00<6!|+#33&R)@RA8V9YRjp$HS9?CGq*xDSDRbX#i;}mateEF{fqTI zt?X}Efkq_Ap*_ETgaikOBbQ|;47}hwX44K`(DUI@C)QiG&6UJ1UmRn*Q@6%e`+x(gpQp74O{;yli8YLCV}qD z4gIyZd_(8ED~WWaeXOb0^r=9=AiDT}by~+$KVF~M{ywbQl zng-h?a_E;yX?DCr4|_h7JMc7>xgWf7Ek-VmH^hCYunVp3{(d{---&%-GZ=rK#V5Jo zJvP8b!2AA5?9)G8gwzB6ze3TU<5*Pqms^Q-?C9-CN~4hb-`U0D@kAkTWn23``cao^ z8IWAp8h7`%ZA+eI?w$sJktq5m>e&0@mQn>2BdpKAxbj1$m$8Z;`!iFvl9($Lb9Ff? zT^6cTZ~HgIeR6R*;G(rzpgsJP41Fx9Df;G6{;k6T(i}&8hX(jHSC@~#X@70h#)g(( z*9vUC+a*b%oAdf1$}Z3NR;|c5nY4^Z51pfqk(tmJbB;Q#ka#tf5eae;-kq$I{xO3<(TI$0lSe-JQzJ*es;il=Kn_?&?E zfLbs{qErPqm)-*ZfwbA*D-shgb|1;X;cH*yA|q8gS=HiosF=-kbdk6--SR+`F^H_` z0*i`J==@XSe=HT;_``G}ulE=H@*3GU*?gVd@h*`eT^GKjI;C@8+h~;(u3bA#b&bN{ zYw>dJ$(;RfHDLlndS`CWOE=g0jOocCc&;w(dOzrLf4-DK*MD@P_;u&CbfMw=#Q-B` zDq8hGwKN-O7(hQA_bP3f5XrZH+@*FGw~ppmDgNWcf|Lf*Pc%e5dw1DcJ1BWm!z7z3 zr^toEU*P(>G#;_1X}Rz(5lbDtCui%hY^d3lm)kw0vyk zX~K4$AG#7cG`6s2%9g9zsaQ9o?;3yzW4Pt!;NlS zzI#G7tiq&@eV&}qDtY(e$1JwscAfle%Al{3>Nr%``n?`Jac^CdOXUbFgI3;m{RkA~ zokl+lxuw9=%W&MmzA+G%ZdFMMP&N2^6BWjG2Lt|xKx)lMCR@b0n+xgw<)&Dwi?}>- z+$_e|@M;uW@3z6)q&L7bYitZ%huzGqH_qHOr&G5o!?(8TJv_MN1ka|&c6_!Q>#PgHSFoPWiLg|k_{ zQd#Zy&BPkU(0OE5S35!B5qb6%T3Wd#J(zBl8dw6I#xIDDF-LBPi-jXv1E?!gE|1OIdTejK)+U3ooC^otSIRsWZf-`&K}6}s!407Y58zH zK(oYx*7sN1O|Z_1YIJS_H$E@DH(hB4QKNCGQT3PTvwYoe2&8WKi5`5tU-r4!>_V3XUT}N)>8V;+z-!@-IGCKiD>E9RC(K`NMx=;Qp zf$2g^t?)zpU0L!BZi(oE#)^Z_biT*Svh>r#%1=O+Wo37G`Q)4@k#Pe?^mgBIugC)8 zyEICH=`{A~^x#X&%tr-$j|(nXrIrGQYNY+C3M+LO;yUU4-|v>a5#P)XYp>_|C0f0n{_p0mvwWmghfd%!Cm}$qBDxOqA3htLs~ghSA1>6^dVgd~ zVHHBBy6;Pp=El;dkTE=ttp~BoOJ$L@EB3Z37T1kTNG3tm4PY5O-7hP5DA$-k=vV&6 z?RiAm;W~*o)R7!x9>u$&@|&D4xMmJ*y+^-6t!F0u8G~78t&Bs#W>w_NbW>W9M3tXWXRf zI86FWVx%iXXh6MJ>dg#?lNu{K@S#nzMIG4PXQd%!Bvc*H0c7F_Y=adptJr*cHevMQ z%?Xu~q8CFw>^L*S_83kVhq=)hf0%_Lq}SE*g(Da_A{kXVZfAd*YCwp~bG32wi&SNM z#QZ7}Ug5-=+s^uqAh_|}gzya<(&E?XAZ%0ybd9nraj?|z1YfPr*{N?Q{ji}YG`T#| z=uwJZHIMlsmevnenT#-)t$L*=2wh|1EYXW?_36TR?L!sUItJVxaC0$Gb|gq4{|4gA z(v0ODFj!T)jc5>65ys)* z7$aBHfbKdz@QJq1b`NT`344*g()$>5*Ey`TPB7WI;|_8o8t9-_4ikFub|I{66>ge> zHA+6onzFKY*eaiA!77SD*^&LyumAR6gSvxY6Q?;!AvI{rZ##!G$%ZfIgce4F`aF;e z?jVh%+B-vj69ei~bh_zA9w}S4B4rzRKQ1~u$gwVu_x5PlRKDXX2(_2Mm7fs%6{SS7Qh1gWT8xaxc=f8`mW38ukIZxwU;lmHABwFSg50*o zrj%f%j~IKR?N5Dxwrq|sTa?!pd{b3sFM&~{4~_^YH4$bI^Fq2W4-y`))^|7fS?i0) zJ&Z9wY!8%l7@gAr`2{fqA;L;ptQR*X2|xUtrT47KK%XN+dydN$*M?65LuXTRabgERR{n>;E;(&vS0_@COY!p<%5LsRqGpER%~YjkSK zwBo9-2|-ZFiU3TT&S+@}3gDT35t0IXTzX@yHA(v>Y8;-mZNySQ&fE7RJ1^tzJfvdApX& z*!+tE)Y{oR%jk8A)3EiI3i*(TOwP!;B3hAOj?KQ6^h-q~1V^166uYS~mH*2Hh*0}r z`R3u1#^LG9IW|^QT^|61H(T1Jz?n;(Z>52lU0BO>Q6*zgpP*gTFk2Uw)!3zt>3F~_ ztil4!R*-j}wjh%&(kSB%}X=u4RbFRp@^l+$SmM@nW9B;yGbf@nasjFMEE{m9Oe

}qal5$moSACwfNXLXG5|3R0AtBcN` z?%yS)&>O>sqxU64U~C3&Q^>z-Zt}WuX4Wh3dKj9EO zfSbV!c3e;EOeKHQmWEw#NM4;*tw-2o@x&kKT?rsmy-F|$jw-F>WgA7?C@{O1qPg*J zf92|RTBMh&ptHADFc{T+cB?+mOj>h2HKgwkxq6w&XBxPc?>=JKvU2K9aU93@vp-R% z{5T=P$9U}AYZ5QU{3%7}YZ+ACWXw#-U zWyxU(OP#Q9-2AeGmCwcp`zWghf2hvsOjWjDQbU?U`v0&a--f1`v0Bd8HLiLmo)PKz5!A1|XVO+89 zm3h2~6yI~cpWor!_yt-?Lt>z`c0a7cJAW)#d8N8nNIf0H<+v;s4{0guDD(?T7Z<~$ zd`$vpZ_QQgFaMT0_d5&+(jwGU?M1FqUu6wjA-9z?mRM}(CmSdK;2e$Na}F-8jbhgN z9)@AIQeghf{xCC^{9P%VdYW1PP#}2BJwWt z0Hd8%st1NK5%h+)UB^mVwh{e#8TIm$xxgGo6I5;e{~VUeeMGRpM_Z%=eH5$X1}?Z5 z`|*_Vp~K&ziz45-Ih9y>EOr(Buy0&n$dbQ4$5eSr=Ti z#~7^n8dmem;$0D4+6eV7&G2D~d@ z+R#u8+nw_N%7_U_1e53P?~&10^m|ZUXrZhVp04lQLsGos%0fRDhS=@>8TOAAxK;Cy z9GZw_1pfSxD5~xoR!INI?tU0wrKDd6^Tv{jL>`Xb49kBaNPlhMaIfh_nq_)zB7NcX z05XeQKz`@BDUx7*i!V~%dc8XQ#ngBw0A2tSr(npSCrNy5Z7>48v&Zz?0{%FRElh_h zN2|?#EhJL5HQMIu6m1=ypTR?tVymHK)xQvS9ir7FzMp?CjlND39PK`od#GytVhZWp zQ1@>MTE1*Ip>hnXSWa?XbMH#708@j12yPbm`JfcqIgmJepn$5YgkJn_%5I)mr`Q(k z-a0yFR3A`houhvf&|wNpIsV{2p%MqhR@`@R(l6`}iufEgI*UxWq~26?WTpZCV{JtG zYL?&#I98fyf_;2S0?_V{=Aa4t^x%vy$pF$_Lh7W2f*~5uPvGYh;vZhMv|u+Z?2t0~ zcYPXdxbg6OS*LUjR_=jLDt)ab6;?g1IuySLG@UE;jLpt-wjLX&RlY>fnd@f&?0NyT zht5vhP^};k6`U76$%&I)iWPNxG6KPjdh`S6>g9GN@;KObQsLG zKyjfrPR0PU1B0a0=)3@9eCDl?mB9rFdlTMtTAeZv2}F*|@JWleq2+H1bt>>x!^wTk z+I)cgsZwzCMwoRpW_*!3IySTQu!`HWugAXe(Ai(a9Rsu;*0#o6torxwNMxPzEAjt` z>70Vw;HCQ?AnP`RKQ;2R8h%;LI#tx^(MO*lMWJe4_?)Q571P`kTmN#(ez21V!<6+S z@Uap+y%#8&cGgdf+E@y$dUx3g#)=#5k31Vqv0p!%L`*=-PiQAiSg-d9lKRZQDuJ-| zA96zwwomG+4}X$vR*IU=NC!vL<`rUTbf_uRJC4FS;k&HtV<=<)p(qymH)=MDV^aqK z#%sid7K|~!H`J!7hRr~Z!emxgWq6#GpQs%c#BM+scvNGz|Gi4G`;8Z~dP8)+51iB8 zw)0fazNz5(iK$LJeC_4e^8&@wT(DZ~~>SStz3P(>V8CLNlZqgv=2K-|Lu~si@XFwMN>QE^k zVS2U_A?Q$?M`NkU}^!M8m%O&T=kW>dG}1s2I~hxp9Y=a=1XX-(fB5) zej3`e5Et~R^r%?CZK0)UZsF_+tSOGIBMdrtMf#oJjGF9U`*P8t>i*TWed$Z2WNUZ* z_1Qw4Yr+Q0@bD?hD0P-^v}?FpPBg~zz5~g@J#J76C695|P>1l;OS8%~hZh5&-9Ji# z50%&56ZK4FC9}{jHL0!=qo9Yd(GGHCEX2|-F(f}q6@NMT4P3rQd{Q!=bz-8N(Z^!N;;ZzAWRf@C?X>mG=_NgyQX_?Jv$m(9$W>P;+e}O|&w&DjbsJPdWp0A2$yLr*!BY73Z z5d*BCaTI)w=sTlofc>n}@v_tSXIK?8(g`G_06u>SD*fOZJ~visq3lBVS2+cf-r$UQ zZ(8A0g&5M$IV7w5nqL(m$VS0X?=yy-e6>S>Ca3wZNT)b{GF39_gJdONflqc-j$b~o z2l@@h{$KVfC)V?#We*)@xYC;L^<@cHo>8axRMbSzw|eYTl|8pkabsQJ(3`z{>5H}c z`psz_Y6t)hvzL^=}P#++XUl6v`-j)SuXd6BynjNZ!&c2hnyE&4*K$nXn31Zk)cm+lx;> zya{T?{MRtSu?^3Y9bS&O$*mW^vRUpv!J3Tz12?3&Y62b_oiZ$24O(75Z)JWb+Rj)ACbK`f<&tSwtT$|Sy z$41kRPiM-jnPY9PKrLyI`pHm6LusMsrO*HpmE){Kp1^u2t%6nW^;GB|!4k!Ik8oav zjM?DBKh9G@W0gEwiU-M}0B)}olvoM71RccgiZBCs)L?q_GX&JDhegx4k2&cNatr5w zU)1#2USb8&`etO5Vk z?0}K+*2*@a5yt*X{qg0@8jEz~jcylVj>-042p1PBnabI#xUiCRD!ouw3?u-wwsqwF z8(@m8-Lk7q@v154g6yvx_tRDa>}oqpVda)wfI9(;ZVGt1v^{<|X?vC_(i@IJC+2I_lusrT=$h zF1lPc*Neb`;Xgrdf`p$w)~MzQW0M3_FYRKu{2$VU82J^B=X1#^<&P$_`=S$Ey04WU zTxG;hrFNLhWC*p+sH3x=JVcBJ9*7>eO20)n671SxQhZQlHMRP8FyO}yai~OTsbms0 zQ3b$C1Cn!>jMHDq{VX1ab^~_Q!z+f75+_AuwiN0*wA_#M#0|rU{+NlB%>Y+TNT0Gj z`3^LKMSJjz2(?lwg~ixDl_5%rzzZ}o_6Fj9e)T7gpH4=BgT1zmwJpC@g(f%&0`}8B z%7Y&qlP3aFmI#nmT`|R3+Lwzp+PLXt|5g%vlY_$fvse7zjus0D0fA##r+i4G4K-2Y zC#H95NGoYfWP#ZF_v$^Li{PZpm}fc&)aL?5doPcb835Cr6`T+EzzcEvLtmXcbAb<^ zw!_Zgk6Az7YA@*vb)(G{_W-B|zrf76z^`X%jOgqIIaqi~5nUup3vugzzg&rA^w(zR z+qCzvIV~nGR=47pDOcNTzuBw#5a=<=DMvGa)g zPw$^pmq9Fg&b#BZrPSoml(149rZS!fioV*Dy$z440U3MXDJmI?RZqLy0}IKSxN)o( z8+8wIZs#q(|KTg6y;Z(=96>xfpUsr@SP}I^v zN^R;ZVrDaWmNrM5-<X@k6JyjvA3;jHhma|Y|7!Vk& zgf(UK_6~cC;!|b!YTjke=nBiUqQdb#I9TY}!s5P)H+^c;9cW(QO8O%n5J^8Xfktd*qrn)+?-gP`m%B&q zi^}7jKm`yMW8ITFOMN#!QIB6$SWx*75tnCMaNg*_J*WuwBh~AT>0($nS8%&zmFQDp z$dL65niDtTV%!Kg1`6epWoQGNG`$`doy;Zjaa`keyL0F6iJMae6FIgnhAfzU%m@V+ zm5rQihLwS~b6{-bVR1ZSzBI7(Yj+V6T-8V*7I`ptWArGdy~8pnV>fALpi~NQLZ7;^ zpaj35=md<~-(tNmF69UX3?ua}A7UIn)q5i1iPYEGlhYSbkfeX`5epkxtzk3Qbu| zlgA`7ts%IvF4HJ}-98akyRnjCo{u-`A4&b+r?s|o`4wdYAHs-yh91p$7C_|+EdYH5 z10`!*=n+W9g>V&dfU1H!J}ASZi&-?`2IlDOAHnu306rD`y>jT)4^@S(X4XhN2{g9i zj-ym98+RT|d0ejIFJCM5>S{mT-8uGmRRqkJ3sMO_AQDrv77Q zv$t>zaVpVF6eBguE%9M2u?E-Oleft8z5+~W`G}KXD(Yc;7m4{Op>Le(k`g1UK7(1# zt6g}$n=Tdn{T4pu>v!c;xRCd_WI$Ali13x=U_0T!Ga-U~9W88q-lU+RLn2`N8Ouho z^0@SvC>$DguHWx)?^*ms-{PVq%dn(U3vrLj9zITDqQZ`H>Wsp@Gf%}SG=m)Vh}F$ztQAbwVGdDgd!28j&yX9wLW&s! zNR~6`nYg;ULAq8zi<;gUchAV5ib67Y##l2 zy+%gaD(|~G4@||{A;TYDSoS>q2o{t23t-^!NDSDEm8j3ao7Ei>KYLEpb$jz}7ciAM zD}trDN+AVVT_lXW<++~>8>Cj8fzJo@R;>%nGq)6+w?(#mNc#1J4W+!hA}?g$0Xqo? zn67qJmss)e%k(xO*&K@z6+}nHA(lCkb6n-|{pSztys$8HiOWTVR)tCO*Q9~if%3n7`uxGzE+OCu zwcVV|tgQdq60952$>85-GHk$lwM(uI+CU1?i{sVnKd0+UNq#eSSKjUKfDDgLnBG1y z^v?f#MRFkph~TgkoKBvM`L_~we8__xpLcjh`GwV|87q`vazJq?SX=mXhdvK>VqUf~ z4sYoTIpt5S)KrE-?>&=cRoBumD7;b5pq!Y07)#I$`)<@U+mo*dE*P~773p*u^6waO z2#thJahX_ySlYMpjx%h<)i43ao~Is`^Ya zMNZkuChEA7+ZJe6$>-C*dzTYf3#1SY82yFG?S&Q)5rTbKS-XLjckTLEc7>^sFcntQ zBeNXCSg&q1N3Bi^4zlQ%mcEBQ%2ab$?(;t-$HYd2%cnX$uuwU#I_6D3($m zR(>gHzM9ODf;r8b0l5LuEIQVZiQ0-|3Y_xzJkZc*CD=bPJ+&J+>>se%D4uTq?Ny{l z0Z5~og*Wa1O&anlcRWu_%o)(x?IZ0CfUNk_R-ik>GyvdFmpu1wHZaKTDGhL zqxsji)n<+)VKbV0_BRq9E;Kb`f=&vn(BK0Ba-gL?ZN;^^b3YFg6R=!q#zM;tcX0dM zdy5PPx@6pJPXHzH7$dGjM|6@6777nXPWV;CIQdNf(*Znv)sMy&Xcq> zhCq+6h6&v8<0}vd2(sKqU3j>fr7&#Xy%qZHcMU3m{wld^Nstkz8GagB?Y=SI&H z&{&BSA-|(i35$9(l6LpFyLm$0M0fK`Dz!~ezL?yEInsXAFR!bHe;ZL>Gd(#Hv?<$%`^b)oi?x%(jkylCPb=juPlF znMo&o961=NZ_$gd{xp1ZY2dNDOS!=XVj!M^A z+$z`EK4v=m{Bs{&I4W)({`&<5*^BV#z{IBAI_d+9Qx;~ zby?2zEjzUUeZWBDo5cz>%;z||z)<+6UtC)y60yD5J5`oo_zSM;l21@CY<0_|)NME5 zs)kHCMBa5YzB#N=W2aR?y9((~WuYwwf+HAc2mvU>NYlxOTvGf^Ye3za?*f-qUs^`a zT3>RPh9*Jf%3*bf|kqtnD_Buxv!<9N>BbuD#uYv-q^ z%RDnd7a3O4M9Y~TNISS@9K}JDkdg@>x8E6@n8jF=6qiDV+}{!V)(o?ykcr0sxBGEx zo!X;pc=r{H^vw6ztV5VZXBa4~(ujB$rZQ|AaGN@J7#q%2nU9gJ)g6dcj}zYB1& z@iFE0vMQVxa|v7tDHS$gwX$Ihc#M^DXRC>J@Zk?dC(3uB_s~*W&m-01DFMQGWjj5x z5po1@1gPl!v1Yra@qPG{D;$bYLM3qOwpl~7f~l)#n< zP+6`!NYe3EE~4RFR#_e=7YctPRBt6$He@`%e5m}f$M%yzC2S0<1}hRPjO>HJY~ z*dx(nbMbjv*;o&k{qzBdF|lS;UNVKziV=gbLq}UOCwr8GT5E9oRYQ}+>DhbQ1R=lj zgcNJN8|D)$Mx3#c+t@lhqcDUnHGVt0&EyQ{b5)=52B(VTzw=pQ^ba3`JB@BU^lS`_ zJEiLzgU#Acd_!}FMxCWC**FP^i#P}bYzNs78)#uSejEtYLbG>JJ7Igtho2oKQ;XW~ z4eMGO+t!_;G^V6c&R`5Tg+Pz2ToN(aybq4Q0ssie_{`t*DO%V7FaZ`{MBobFc9|pV z70o5ayHGJo9$$&Pgbs)pWNzduAcbh?~U?_P)(ve0S*3H%eNF&a5XR=!J#4c z;t992n7ZJr{*%`^dU1d-ALE8!3i#v;3r4r%j+JFCe=%3Vj=8{aXe zs)jrcUBZ=;LudcTUXj2ub>K5!{HHFHJ}Trx(PYugbQ8yK7&sqX;(;|UWjk3tGs3zuceeX)i4i_jA8Qz2Bc%DxN8 zXw!$+9jBtEHd1y90bYG4f8DcJM)Ab!M39tH5zz94*MAvnhA377@buNupSOUU3j8~> zd6&hk^ENRCp9T?_QUHk<=(&9Q^MJ^pi;nKOYNR@?L=RCSmKMJ5UQJQ`X!i~(gD*P! zs`RobzJG3Ra_Pg+WZUXUmMU$ilpwfcEti6)mw(~MZ0q!^sza>#jv!-+7B6F3QuMWg zVO!rXwD+lF1BBTito?ml-CV3vxuek~TKuOX^N6sol$v*{_%nAuD7i81eXm^Lz(Z~I z2Xj_Dts#G0&C;PV_Wkq*1QvB7+Post4={v;gk7b9u%#DC_bh(iJm$rqog^{JEx6NE zrs5^2SEL$|98#2WV#iG@L6cq|)SuTMSfGocPl65wUd^|5Lbpnb(;t>-Qu2jvANLgv zdte0vED-3C@^BdyHWLL(7{G$WA02z@JG!T-U^Q7HZ(7Bs&vchkh(p&}KvnS{MG^i6 z4r){gJp9p7WyWOEiKA2Cm6EXIn&&gk|Fc6^78OpPrX4ExCFE=SD$xcH;C2eB^{XTI zaxz_Cef*Yj==w_i_BTGXP;8C&f? z*QEM>={jFM8)lWAR870pG4XEWsl%%K|82S5b=9hVz7p_6i-d(Iyvq76&a#PV zR;VbQV|n?mg}&(ehClg%tK%IjgtnTR-u)lxH06XxXqH0soAZbB_Rm)XX=6Nge1uoG7 z9vQM_S~2h53n|W`y{{R9+=08rv~MohI_v4-BU^7fZ0-A}#b5{AOSTJm+(J;9yw%pD zX6u62GJ&@HKX5zQwq~j8T!Hrv-Mk^QSB5cu09L03{ToDO7jikM0WAcsjW>D}^jqCF zT0DEZ@K^KO_MD*%M!+V)lGVU6?LpX)eQVXEmq}R`NIJv;kBitJ!nW?0OxTVlu2ADf zE{A!*0g3%nwVcBD+AgT5bGx@WOnQk{zRpiZ4HhP`3BF%N|HdqPbbiV5)7x)kzC3ID zZ;27>0^mrMgWc7evsbQY`l`l})wr+e;=8U_!2&B77;1qL!N8y)eTJ2lf#CvhR~!Qa mc;sM|90DP5A*JW%f2r=u1xt!e4gwD_V(@hJb6Mw<&;$SznOm^{ literal 0 HcmV?d00001 diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/manifest.yml new file mode 100644 index 0000000000000..4dac02c33371a --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/runtime_fields/0.0.1/manifest.yml @@ -0,0 +1,33 @@ +format_version: 2.8.0 +name: runtime_fields +title: "Runtime fields" +version: 0.0.1 +source: + license: "Elastic-2.0" +description: "This is a new package." +type: integration +categories: + - custom +conditions: + kibana.version: "^8.10.0" + elastic.subscription: "basic" +screenshots: + - src: /img/sample-screenshot.png + title: Sample screenshot + size: 600x600 + type: image/png +icons: + - src: /img/sample-logo.svg + title: Sample logo + size: 32x32 + type: image/svg+xml +policy_templates: + - name: sample + title: Sample logs + description: Collect sample logs + inputs: + - type: logfile + title: Collect sample logs from instances + description: Collecting sample logs +owner: + github: elastic/integrations From ea1e6ed240a419f5f4f705c980d34c19c29af47c Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Wed, 12 Jul 2023 11:01:06 +0200 Subject: [PATCH 57/97] [root] add more logs for bootstrap and shutdown (#161629) ## Summary Looking at the logs, I realized we were not logging anything in `info` level when Kibana is starting up or shutting down at the `Root` level, making it quite awkward when trying to understand when an instance / pod was started or shut down and even why. Also, we were not logging the stack trace of the shutdown reason when present. FWIW, this is (the exhaustive list of) what's displayed in some shutdown scenarios (most recent to least recent): Screenshot 2023-07-11 at 11 41 27 As you can see: 1. We have no idea why Kibana was shut down 2. We don't know where this `no element in sequence` error even comes from This PR adds a few logs: - `Kibana is starting` during `bootstrap` - `Kibana is shutting down` during `shutdown` - The shutdown reason's stack when provided - `SIGINT received - initiating shutdown` and `SIGTERM received - initiating shutdown` when receiving the associated signals --- .../core-root-server-internal/src/bootstrap.ts | 15 ++++++++++++--- .../core-root-server-internal/src/root/index.ts | 12 ++++++++++-- ...h_size_bytes_exceeds_es_content_length.test.ts | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/packages/core/root/core-root-server-internal/src/bootstrap.ts b/packages/core/root/core-root-server-internal/src/bootstrap.ts index 90e603fb20d48..5c35e03ecf656 100644 --- a/packages/core/root/core-root-server-internal/src/bootstrap.ts +++ b/packages/core/root/core-root-server-internal/src/bootstrap.ts @@ -49,6 +49,9 @@ export async function bootstrap({ configs, cliArgs, applyConfigOverrides }: Boot const root = new Root(rawConfigService, env, onRootShutdown); const cliLogger = root.logger.get('cli'); + const rootLogger = root.logger.get('root'); + + rootLogger.info('Kibana is starting'); cliLogger.debug('Kibana configurations evaluated in this order: ' + env.configs.join(', ')); @@ -77,8 +80,14 @@ export async function bootstrap({ configs, cliArgs, applyConfigOverrides }: Boot cliLogger.info(`Reloaded Kibana configuration (reason: ${reason}).`, { tags: ['config'] }); } - process.on('SIGINT', () => shutdown()); - process.on('SIGTERM', () => shutdown()); + process.on('SIGINT', () => { + rootLogger.info('SIGINT received - initiating shutdown'); + shutdown(); + }); + process.on('SIGTERM', () => { + rootLogger.info('SIGTERM received - initiating shutdown'); + shutdown(); + }); function shutdown(reason?: Error) { rawConfigService.stop(); @@ -96,7 +105,7 @@ export async function bootstrap({ configs, cliArgs, applyConfigOverrides }: Boot } if (isSetupOnHold) { - root.logger.get().info('Holding setup until preboot stage is completed.'); + rootLogger.info('Holding setup until preboot stage is completed.'); const { shouldReloadConfig } = await preboot.waitUntilCanSetup(); if (shouldReloadConfig) { await reloadConfiguration('configuration might have changed during preboot stage'); diff --git a/packages/core/root/core-root-server-internal/src/root/index.ts b/packages/core/root/core-root-server-internal/src/root/index.ts index 82c7d8feaec78..42949fda6b31d 100644 --- a/packages/core/root/core-root-server-internal/src/root/index.ts +++ b/packages/core/root/core-root-server-internal/src/root/index.ts @@ -81,7 +81,7 @@ export class Root { } public async shutdown(reason?: any) { - this.log.debug('shutting root down'); + this.log.info('Kibana is shutting down'); if (reason) { if (reason.code === 'EADDRINUSE' && Number.isInteger(reason.port)) { @@ -91,7 +91,7 @@ export class Root { } if (reason.code !== MIGRATION_EXCEPTION_CODE) { - this.log.fatal(reason); + this.log.fatal(formatShutdownReason(reason)); } } @@ -159,3 +159,11 @@ export class Root { this.loggingConfigSubscription.add(connectSubscription); } } + +const formatShutdownReason = (reason: any): string => { + let message = `Reason: ${reason.message ?? reason}`; + if (reason.stack) { + message = `${message}\n${reason.stack}`; + } + return message; +}; diff --git a/src/core/server/integration_tests/saved_objects/migrations/group2/batch_size_bytes_exceeds_es_content_length.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group2/batch_size_bytes_exceeds_es_content_length.test.ts index 26a26764c04b4..95baed313bd8c 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group2/batch_size_bytes_exceeds_es_content_length.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group2/batch_size_bytes_exceeds_es_content_length.test.ts @@ -82,7 +82,7 @@ describe('migration v2', () => { expect( records.find((rec) => rec.message.startsWith( - `Unable to complete saved object migrations for the [.kibana] index: While indexing a batch of saved objects, Elasticsearch returned a 413 Request Entity Too Large exception. Ensure that the Kibana configuration option 'migrations.maxBatchSizeBytes' is set to a value that is lower than or equal to the Elasticsearch 'http.max_content_length' configuration option.` + `Reason: Unable to complete saved object migrations for the [.kibana] index: While indexing a batch of saved objects, Elasticsearch returned a 413 Request Entity Too Large exception. Ensure that the Kibana configuration option 'migrations.maxBatchSizeBytes' is set to a value that is lower than or equal to the Elasticsearch 'http.max_content_length' configuration option.` ) ) ).toBeDefined(); From 47d099e22f537df820858a31e00f05343c026e25 Mon Sep 17 00:00:00 2001 From: Jordan <51442161+JordanSh@users.noreply.github.com> Date: Wed, 12 Jul 2023 12:09:41 +0300 Subject: [PATCH 58/97] [Cloud Security] Adding vuln filter to the scores index (#161648) --- .../server/tasks/findings_stats_task.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/server/tasks/findings_stats_task.ts b/x-pack/plugins/cloud_security_posture/server/tasks/findings_stats_task.ts index 756cf739711d4..14bb41964e8b6 100644 --- a/x-pack/plugins/cloud_security_posture/server/tasks/findings_stats_task.ts +++ b/x-pack/plugins/cloud_security_posture/server/tasks/findings_stats_task.ts @@ -14,6 +14,7 @@ import { import { SearchRequest } from '@kbn/data-plugin/common'; import { ElasticsearchClient } from '@kbn/core/server'; import type { Logger } from '@kbn/core/server'; +import { getSafeVulnerabilitiesQueryFilter } from '../../common/utils/get_safe_vulnerabilities_query_filter'; import { getSafePostureTypeRuntimeMapping } from '../../common/runtime_mappings/get_safe_posture_type_runtime_mapping'; import { getIdentifierRuntimeMapping } from '../../common/runtime_mappings/get_identifier_runtime_mapping'; import { @@ -181,9 +182,7 @@ const getScoreQuery = (): SearchRequest => ({ const getVulnStatsTrendQuery = (): SearchRequest => ({ index: LATEST_VULNERABILITIES_INDEX_DEFAULT_NS, size: 0, - query: { - match_all: {}, - }, + query: getSafeVulnerabilitiesQueryFilter(), aggs: { critical: { filter: { term: { 'vulnerability.severity': VULNERABILITIES_SEVERITY.CRITICAL } }, From 5fca22a79db0ad72d539d7ee297211653e607026 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 12 Jul 2023 11:10:03 +0200 Subject: [PATCH 59/97] [Synthetics] Refactor e2e tests for silent failures (#161638) --- .../journeys/services/synthetics_services.ts | 69 ++++--------------- 1 file changed, 14 insertions(+), 55 deletions(-) diff --git a/x-pack/plugins/synthetics/e2e/synthetics/journeys/services/synthetics_services.ts b/x-pack/plugins/synthetics/e2e/synthetics/journeys/services/synthetics_services.ts index 9f815a2970f7f..47199b38f0a3b 100644 --- a/x-pack/plugins/synthetics/e2e/synthetics/journeys/services/synthetics_services.ts +++ b/x-pack/plugins/synthetics/e2e/synthetics/journeys/services/synthetics_services.ts @@ -200,70 +200,29 @@ export class SyntheticsServices { }); } - async cleaUp(things: Array<'monitors' | 'alerts' | 'rules'> = ['monitors', 'alerts', 'rules']) { - const promises = []; - if (things.includes('monitors')) { - promises.push(this.cleanTestMonitors()); - } - if (things.includes('alerts')) { - promises.push(this.cleaUpAlerts()); - } - - if (things.includes('rules')) { - promises.push(this.cleaUpRules()); - } - - await Promise.all(promises); - } - - async cleaUpAlerts() { - const getService = this.params.getService; - const es: Client = getService('es'); - const listOfIndices = await es.cat.indices({ format: 'json' }); - for (const index of listOfIndices) { - if (index.index?.startsWith('.internal.alerts-observability.uptime.alerts')) { - await es.deleteByQuery({ index: index.index, query: { match_all: {} } }); - } - } - } - - async cleaUpRules() { + async cleaUp() { try { - const { data: response } = await this.requester.request({ - description: 'get monitors by name', - path: `/internal/alerting/rules/_find`, - query: { - per_page: 10, - page: 1, - }, - method: 'GET', - }); - const { data = [] } = response as any; - - if (data.length > 0) { - // eslint-disable-next-line no-console - console.log(`Deleting ${data.length} rules`); + const getService = this.params.getService; + const server = getService('kibanaServer'); - await axios.patch( - this.kibanaUrl + '/internal/alerting/rules/_bulk_delete', - { - ids: data.map((rule: any) => rule.id), - }, - { auth: { username: 'elastic', password: 'changeme' }, headers: { 'kbn-xsrf': 'true' } } - ); - } + await server.savedObjects.clean({ types: ['synthetics-monitor', 'alert'] }); + await this.cleaUpAlerts(); } catch (e) { // eslint-disable-next-line no-console console.log(e); } } - async cleanTestMonitors() { - const getService = this.params.getService; - const server = getService('kibanaServer'); - + async cleaUpAlerts() { try { - await server.savedObjects.clean({ types: ['synthetics-monitor'] }); + const getService = this.params.getService; + const es: Client = getService('es'); + const listOfIndices = await es.cat.indices({ format: 'json' }); + for (const index of listOfIndices) { + if (index.index?.startsWith('.internal.alerts-observability.uptime.alerts')) { + await es.deleteByQuery({ index: index.index, query: { match_all: {} } }); + } + } } catch (e) { // eslint-disable-next-line no-console console.log(e); From 707a637f426dbef9cb3201b356cab5af118c8850 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 12 Jul 2023 12:27:34 +0200 Subject: [PATCH 60/97] [Synthetics] Fix parsing of response check json expression (#161634) --- .../synthetics/server/synthetics_service/formatters/common.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts index 1812917af9d7d..3a8776dd0cf05 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/formatters/common.ts @@ -10,8 +10,10 @@ import { ConfigKey } from '../../../common/constants/monitor_management'; export const PARAMS_KEYS_TO_SKIP = [ 'secrets', 'fields', + ConfigKey.MONITOR_QUERY_ID, ConfigKey.LOCATIONS, ConfigKey.TLS_VERSION, ConfigKey.SOURCE_PROJECT_CONTENT, ConfigKey.SOURCE_INLINE, + ConfigKey.RESPONSE_JSON_CHECK, ]; From 90b7b1a3c8aafbe9fbafd9f4d28732c69912fdbb Mon Sep 17 00:00:00 2001 From: Sander Philipse <94373878+sphilipse@users.noreply.github.com> Date: Wed, 12 Jul 2023 18:34:14 +0800 Subject: [PATCH 61/97] [Enterprise Search] Add reasonable error handling for connector index absence (#161729) This adds reasonable error handling and returns for connectors in case the indices haven't been created yet. Specifically: - Creating a connector or sync job targets the concrete index so the index template can be triggered. - Fetches of connectors or sync jobs return undefined or empty arrays if the index doesn't exist. --- .../enterprise_search/common/constants.ts | 14 + .../plugins/enterprise_search/server/index.ts | 1 + .../index_management/setup_indices.test.ts | 399 ------------------ .../server/index_management/setup_indices.ts | 340 --------------- .../lib/connectors/add_connector.test.ts | 153 +------ .../server/lib/connectors/add_connector.ts | 31 +- .../connectors/fetch_connector_index_names.ts | 22 +- .../lib/connectors/fetch_connectors.test.ts | 111 ++--- .../server/lib/connectors/fetch_connectors.ts | 14 +- .../lib/connectors/fetch_sync_jobs.test.ts | 12 +- .../server/lib/connectors/fetch_sync_jobs.ts | 5 +- .../server/lib/connectors/start_sync.test.ts | 10 +- .../server/lib/connectors/start_sync.ts | 4 +- .../server/lib/indices/fetch_index.ts | 50 ++- .../lib/pipelines/get_default_pipeline.ts | 38 +- .../lib/pipelines/update_default_pipeline.ts | 11 +- .../server/lib/stats/get_sync_jobs.ts | 203 ++++----- 17 files changed, 258 insertions(+), 1160 deletions(-) delete mode 100644 x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts delete mode 100644 x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts diff --git a/x-pack/plugins/enterprise_search/common/constants.ts b/x-pack/plugins/enterprise_search/common/constants.ts index 0e1e7be69f492..14da6aeca4919 100644 --- a/x-pack/plugins/enterprise_search/common/constants.ts +++ b/x-pack/plugins/enterprise_search/common/constants.ts @@ -199,6 +199,20 @@ export const DEFAULT_PIPELINE_VALUES: IngestPipelineParams = { run_ml_inference: false, }; +export interface DefaultConnectorsPipelineMeta { + default_extract_binary_content: boolean; + default_name: string; + default_reduce_whitespace: boolean; + default_run_ml_inference: boolean; +} + +export const defaultConnectorsPipelineMeta: DefaultConnectorsPipelineMeta = { + default_extract_binary_content: DEFAULT_PIPELINE_VALUES.extract_binary_content, + default_name: DEFAULT_PIPELINE_NAME, + default_reduce_whitespace: DEFAULT_PIPELINE_VALUES.reduce_whitespace, + default_run_ml_inference: DEFAULT_PIPELINE_VALUES.run_ml_inference, +}; + export enum INGESTION_METHOD_IDS { API = 'api', CONNECTOR = 'connector', diff --git a/x-pack/plugins/enterprise_search/server/index.ts b/x-pack/plugins/enterprise_search/server/index.ts index 2918641814341..1ba4584517912 100644 --- a/x-pack/plugins/enterprise_search/server/index.ts +++ b/x-pack/plugins/enterprise_search/server/index.ts @@ -51,5 +51,6 @@ export const config: PluginConfigDescriptor = { export const CONNECTORS_INDEX = '.elastic-connectors'; export const CURRENT_CONNECTORS_INDEX = '.elastic-connectors-v1'; export const CONNECTORS_JOBS_INDEX = '.elastic-connectors-sync-jobs'; +export const CURRENT_CONNECTORS_JOB_INDEX = '.elastic-connectors-v1'; export const CONNECTORS_VERSION = 1; export const CRAWLERS_INDEX = '.ent-search-actastic-crawler2_configurations_v2'; diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts deleted file mode 100644 index 95902da5fdac7..0000000000000 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX, CONNECTORS_VERSION } from '..'; - -import { defaultConnectorsPipelineMeta, setupConnectorsIndices } from './setup_indices'; - -describe('Setup Indices', () => { - const mockClient = { - asCurrentUser: { - indices: { - create: jest.fn(), - get: jest.fn(), - stats: jest.fn(), - updateAliases: jest.fn(), - }, - search: jest.fn(), - }, - asInternalUser: {}, - }; - - const connectorsIndexName = `${CONNECTORS_INDEX}-v${CONNECTORS_VERSION}`; - const jobsIndexName = `${CONNECTORS_JOBS_INDEX}-v${CONNECTORS_VERSION}`; - - const connectorsMappings = { - _meta: { - version: CONNECTORS_VERSION, - pipeline: defaultConnectorsPipelineMeta, - }, - dynamic: false, - properties: { - api_key_id: { - type: 'keyword', - }, - configuration: { - type: 'object', - }, - custom_scheduling: { - type: 'object', - }, - description: { type: 'text' }, - error: { type: 'keyword' }, - features: { - properties: { - filtering_advanced_config: { type: 'boolean' }, - filtering_rules: { type: 'boolean' }, - incremental_sync: { - properties: { - enabled: { type: 'boolean' }, - }, - }, - sync_rules: { - properties: { - basic: { - properties: { - enabled: { type: 'boolean' }, - }, - }, - advanced: { - properties: { - enabled: { type: 'boolean' }, - }, - }, - }, - }, - }, - }, - filtering: { - properties: { - active: { - properties: { - advanced_snippet: { - properties: { - created_at: { type: 'date' }, - updated_at: { type: 'date' }, - value: { type: 'object' }, - }, - }, - rules: { - properties: { - created_at: { type: 'date' }, - field: { type: 'keyword' }, - id: { type: 'keyword' }, - order: { type: 'short' }, - policy: { type: 'keyword' }, - rule: { type: 'keyword' }, - updated_at: { type: 'date' }, - value: { type: 'keyword' }, - }, - }, - validation: { - properties: { - errors: { - properties: { - ids: { type: 'keyword' }, - messages: { type: 'text' }, - }, - }, - state: { type: 'keyword' }, - }, - }, - }, - }, - domain: { type: 'keyword' }, - draft: { - properties: { - advanced_snippet: { - properties: { - created_at: { type: 'date' }, - updated_at: { type: 'date' }, - value: { type: 'object' }, - }, - }, - rules: { - properties: { - created_at: { type: 'date' }, - field: { type: 'keyword' }, - id: { type: 'keyword' }, - order: { type: 'short' }, - policy: { type: 'keyword' }, - rule: { type: 'keyword' }, - updated_at: { type: 'date' }, - value: { type: 'keyword' }, - }, - }, - validation: { - properties: { - errors: { - properties: { - ids: { type: 'keyword' }, - messages: { type: 'text' }, - }, - }, - state: { type: 'keyword' }, - }, - }, - }, - }, - }, - }, - index_name: { type: 'keyword' }, - is_native: { type: 'boolean' }, - language: { type: 'keyword' }, - last_access_control_sync_error: { type: 'keyword' }, - last_access_control_sync_scheduled_at: { type: 'date' }, - last_access_control_sync_status: { type: 'keyword' }, - last_deleted_document_count: { type: 'long' }, - last_incremental_sync_scheduled_at: { type: 'date' }, - last_indexed_document_count: { type: 'long' }, - last_seen: { type: 'date' }, - last_sync_error: { type: 'keyword' }, - last_sync_scheduled_at: { type: 'date' }, - last_sync_status: { type: 'keyword' }, - last_synced: { type: 'date' }, - name: { type: 'keyword' }, - pipeline: { - properties: { - extract_binary_content: { type: 'boolean' }, - name: { type: 'keyword' }, - reduce_whitespace: { type: 'boolean' }, - run_ml_inference: { type: 'boolean' }, - }, - }, - scheduling: { - properties: { - access_control: { - properties: { - enabled: { type: 'boolean' }, - interval: { type: 'text' }, - }, - }, - incremental: { - properties: { - enabled: { type: 'boolean' }, - interval: { type: 'text' }, - }, - }, - full: { - properties: { - enabled: { type: 'boolean' }, - interval: { type: 'text' }, - }, - }, - }, - }, - service_type: { type: 'keyword' }, - status: { type: 'keyword' }, - sync_cursor: { type: 'object' }, - sync_now: { type: 'boolean' }, - }, - }; - - const connectorsJobsMappings = { - _meta: { - version: CONNECTORS_VERSION, - }, - dynamic: false, - properties: { - cancelation_requested_at: { type: 'date' }, - canceled_at: { type: 'date' }, - completed_at: { type: 'date' }, - connector: { - properties: { - configuration: { type: 'object' }, - filtering: { - properties: { - advanced_snippet: { - properties: { - created_at: { type: 'date' }, - updated_at: { type: 'date' }, - value: { type: 'object' }, - }, - }, - domain: { type: 'keyword' }, - rules: { - properties: { - created_at: { type: 'date' }, - field: { type: 'keyword' }, - id: { type: 'keyword' }, - order: { type: 'short' }, - policy: { type: 'keyword' }, - rule: { type: 'keyword' }, - updated_at: { type: 'date' }, - value: { type: 'keyword' }, - }, - }, - warnings: { - properties: { - ids: { type: 'keyword' }, - messages: { type: 'text' }, - }, - }, - }, - }, - id: { type: 'keyword' }, - index_name: { type: 'keyword' }, - language: { type: 'keyword' }, - pipeline: { - properties: { - extract_binary_content: { type: 'boolean' }, - name: { type: 'keyword' }, - reduce_whitespace: { type: 'boolean' }, - run_ml_inference: { type: 'boolean' }, - }, - }, - service_type: { type: 'keyword' }, - sync_cursor: { type: 'object' }, - }, - }, - created_at: { type: 'date' }, - deleted_document_count: { type: 'integer' }, - error: { type: 'keyword' }, - indexed_document_count: { type: 'integer' }, - indexed_document_volume: { type: 'integer' }, - job_type: { type: 'keyword' }, - last_seen: { type: 'date' }, - metadata: { type: 'object' }, - started_at: { type: 'date' }, - status: { - type: 'keyword', - }, - total_document_count: { type: 'integer' }, - trigger_method: { type: 'keyword' }, - worker_hostname: { type: 'keyword' }, - }, - }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - describe('setupConnectorsIndices', () => { - it('should do nothing if indices exist', async () => { - const result = { - [connectorsIndexName]: { - mappings: { - _meta: { - version: CONNECTORS_VERSION, - }, - }, - }, - [jobsIndexName]: { - mappings: { - _meta: { - version: CONNECTORS_VERSION, - }, - }, - }, - }; - mockClient.asCurrentUser.indices.get.mockImplementation(() => Promise.resolve(result)); - mockClient.asCurrentUser.indices.create.mockImplementation(() => Promise.resolve()); - mockClient.asCurrentUser.indices.updateAliases.mockImplementation(() => Promise.resolve()); - await expect(setupConnectorsIndices(mockClient.asCurrentUser as any)).resolves.toEqual( - undefined - ); - expect(mockClient.asCurrentUser.indices.create).not.toHaveBeenCalled(); - expect(mockClient.asCurrentUser.indices.updateAliases).not.toHaveBeenCalled(); - }); - it('should do nothing if it hits race condition exist', async () => { - const result = { - [connectorsIndexName]: { - mappings: { - _meta: { - version: CONNECTORS_VERSION, - }, - }, - }, - [jobsIndexName]: { - mappings: { - _meta: { - version: CONNECTORS_VERSION, - }, - }, - }, - }; - mockClient.asCurrentUser.indices.get.mockImplementation(() => Promise.resolve(result)); - mockClient.asCurrentUser.indices.create.mockImplementation(() => - Promise.reject({ meta: { body: { error: { type: 'resource_already_exists_exception' } } } }) - ); - mockClient.asCurrentUser.indices.updateAliases.mockImplementation(() => Promise.resolve()); - await expect(setupConnectorsIndices(mockClient.asCurrentUser as any)).resolves.toEqual( - undefined - ); - expect(mockClient.asCurrentUser.indices.create).not.toHaveBeenCalled(); - expect(mockClient.asCurrentUser.indices.updateAliases).not.toHaveBeenCalled(); - }); - it('should create new index and update alias if connectors index does not exist', async () => { - const result = { - [jobsIndexName]: { - mappings: { - _meta: { - version: CONNECTORS_VERSION, - }, - }, - }, - }; - mockClient.asCurrentUser.indices.get.mockImplementation(() => Promise.resolve(result)); - mockClient.asCurrentUser.indices.create.mockImplementation(() => Promise.resolve()); - mockClient.asCurrentUser.indices.updateAliases.mockImplementation(() => Promise.resolve()); - await expect(setupConnectorsIndices(mockClient.asCurrentUser as any)).resolves.toEqual( - undefined - ); - expect(mockClient.asCurrentUser.indices.create).toHaveBeenCalledWith({ - index: connectorsIndexName, - mappings: connectorsMappings, - settings: { auto_expand_replicas: '0-3', hidden: true, number_of_replicas: 0 }, - }); - expect(mockClient.asCurrentUser.indices.updateAliases).toHaveBeenCalledWith({ - actions: [ - { - add: { - aliases: [CONNECTORS_INDEX], - index: `${CONNECTORS_INDEX}-v${CONNECTORS_VERSION}`, - is_hidden: true, - is_write_index: true, - }, - }, - ], - }); - }); - it('should create new jobs index and update alias if jobs index does not exist', async () => { - const result = { - [connectorsIndexName]: { - mappings: { - _meta: { - version: CONNECTORS_VERSION, - }, - }, - }, - }; - mockClient.asCurrentUser.indices.get.mockImplementation(() => Promise.resolve(result)); - mockClient.asCurrentUser.indices.create.mockImplementation(() => Promise.resolve()); - mockClient.asCurrentUser.indices.updateAliases.mockImplementation(() => Promise.resolve()); - await expect(setupConnectorsIndices(mockClient.asCurrentUser as any)).resolves.toEqual( - undefined - ); - expect(mockClient.asCurrentUser.indices.create).toHaveBeenCalledWith({ - index: jobsIndexName, - mappings: connectorsJobsMappings, - settings: { auto_expand_replicas: '0-3', hidden: true, number_of_replicas: 0 }, - }); - expect(mockClient.asCurrentUser.indices.updateAliases).toHaveBeenCalledWith({ - actions: [ - { - add: { - aliases: [CONNECTORS_JOBS_INDEX], - index: `${CONNECTORS_JOBS_INDEX}-v${CONNECTORS_VERSION}`, - is_hidden: true, - is_write_index: true, - }, - }, - ], - }); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts deleted file mode 100644 index f9c124bbb56dc..0000000000000 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - IndicesIndexSettings, - MappingProperty, - MappingTypeMapping, -} from '@elastic/elasticsearch/lib/api/types'; -import { ElasticsearchClient } from '@kbn/core/server'; - -import { CONNECTORS_INDEX } from '..'; -import { isResourceAlreadyExistsException } from '../utils/identify_exceptions'; - -export enum SETUP_ERRORS { - 'insufficient_permissions', - 'index_already_exists', -} - -interface IndexDefinition { - aliases: string[]; - mappings: MappingTypeMapping; - name: string; - settings: IndicesIndexSettings; -} - -const connectorMappingsProperties: Record = { - api_key_id: { type: 'keyword' }, - configuration: { type: 'object' }, - custom_scheduling: { type: 'object' }, - description: { type: 'text' }, - error: { type: 'keyword' }, - features: { - properties: { - filtering_advanced_config: { type: 'boolean' }, - filtering_rules: { type: 'boolean' }, - incremental_sync: { - properties: { - enabled: { type: 'boolean' }, - }, - }, - sync_rules: { - properties: { - basic: { - properties: { - enabled: { type: 'boolean' }, - }, - }, - advanced: { - properties: { - enabled: { type: 'boolean' }, - }, - }, - }, - }, - }, - }, - filtering: { - properties: { - active: { - properties: { - advanced_snippet: { - properties: { - created_at: { type: 'date' }, - updated_at: { type: 'date' }, - value: { type: 'object' }, - }, - }, - rules: { - properties: { - created_at: { type: 'date' }, - field: { type: 'keyword' }, - id: { type: 'keyword' }, - order: { type: 'short' }, - policy: { type: 'keyword' }, - rule: { type: 'keyword' }, - updated_at: { type: 'date' }, - value: { type: 'keyword' }, - }, - }, - validation: { - properties: { - errors: { - properties: { - ids: { type: 'keyword' }, - messages: { type: 'text' }, - }, - }, - state: { type: 'keyword' }, - }, - }, - }, - }, - domain: { type: 'keyword' }, - draft: { - properties: { - advanced_snippet: { - properties: { - created_at: { type: 'date' }, - updated_at: { type: 'date' }, - value: { type: 'object' }, - }, - }, - rules: { - properties: { - created_at: { type: 'date' }, - field: { type: 'keyword' }, - id: { type: 'keyword' }, - order: { type: 'short' }, - policy: { type: 'keyword' }, - rule: { type: 'keyword' }, - updated_at: { type: 'date' }, - value: { type: 'keyword' }, - }, - }, - validation: { - properties: { - errors: { - properties: { - ids: { type: 'keyword' }, - messages: { type: 'text' }, - }, - }, - state: { type: 'keyword' }, - }, - }, - }, - }, - }, - }, - index_name: { type: 'keyword' }, - is_native: { type: 'boolean' }, - language: { type: 'keyword' }, - last_access_control_sync_error: { type: 'keyword' }, - last_access_control_sync_scheduled_at: { type: 'date' }, - last_access_control_sync_status: { type: 'keyword' }, - last_deleted_document_count: { type: 'long' }, - last_incremental_sync_scheduled_at: { type: 'date' }, - last_indexed_document_count: { type: 'long' }, - last_seen: { type: 'date' }, - last_sync_error: { type: 'keyword' }, - last_sync_scheduled_at: { type: 'date' }, - last_sync_status: { type: 'keyword' }, - last_synced: { type: 'date' }, - name: { type: 'keyword' }, - pipeline: { - properties: { - extract_binary_content: { type: 'boolean' }, - name: { type: 'keyword' }, - reduce_whitespace: { type: 'boolean' }, - run_ml_inference: { type: 'boolean' }, - }, - }, - scheduling: { - properties: { - access_control: { - properties: { - enabled: { type: 'boolean' }, - interval: { type: 'text' }, - }, - }, - incremental: { - properties: { - enabled: { type: 'boolean' }, - interval: { type: 'text' }, - }, - }, - full: { - properties: { - enabled: { type: 'boolean' }, - interval: { type: 'text' }, - }, - }, - }, - }, - service_type: { type: 'keyword' }, - status: { type: 'keyword' }, - sync_cursor: { type: 'object' }, - sync_now: { type: 'boolean' }, -}; - -const defaultSettings: IndicesIndexSettings = { - auto_expand_replicas: '0-3', - hidden: true, - number_of_replicas: 0, -}; - -export interface DefaultConnectorsPipelineMeta { - default_extract_binary_content: boolean; - default_name: string; - default_reduce_whitespace: boolean; - default_run_ml_inference: boolean; -} - -export const defaultConnectorsPipelineMeta: DefaultConnectorsPipelineMeta = { - default_extract_binary_content: true, - default_name: 'ent-search-generic-ingestion', - default_reduce_whitespace: true, - default_run_ml_inference: true, -}; - -const indices: IndexDefinition[] = [ - { - aliases: ['.elastic-connectors'], - mappings: { - _meta: { - pipeline: defaultConnectorsPipelineMeta, - version: 1, - }, - dynamic: false, - properties: connectorMappingsProperties, - }, - name: '.elastic-connectors-v1', - settings: defaultSettings, - }, - { - aliases: ['.elastic-connectors-sync-jobs'], - mappings: { - _meta: { - version: 1, - }, - dynamic: false, - properties: { - cancelation_requested_at: { type: 'date' }, - canceled_at: { type: 'date' }, - completed_at: { type: 'date' }, - connector: { - properties: { - configuration: { type: 'object' }, - filtering: { - properties: { - advanced_snippet: { - properties: { - created_at: { type: 'date' }, - updated_at: { type: 'date' }, - value: { type: 'object' }, - }, - }, - domain: { type: 'keyword' }, - rules: { - properties: { - created_at: { type: 'date' }, - field: { type: 'keyword' }, - id: { type: 'keyword' }, - order: { type: 'short' }, - policy: { type: 'keyword' }, - rule: { type: 'keyword' }, - updated_at: { type: 'date' }, - value: { type: 'keyword' }, - }, - }, - warnings: { - properties: { - ids: { type: 'keyword' }, - messages: { type: 'text' }, - }, - }, - }, - }, - id: { type: 'keyword' }, - index_name: { type: 'keyword' }, - language: { type: 'keyword' }, - pipeline: { - properties: { - extract_binary_content: { type: 'boolean' }, - name: { type: 'keyword' }, - reduce_whitespace: { type: 'boolean' }, - run_ml_inference: { type: 'boolean' }, - }, - }, - service_type: { type: 'keyword' }, - sync_cursor: { type: 'object' }, - }, - }, - created_at: { type: 'date' }, - deleted_document_count: { type: 'integer' }, - error: { type: 'keyword' }, - indexed_document_count: { type: 'integer' }, - indexed_document_volume: { type: 'integer' }, - job_type: { type: 'keyword' }, - last_seen: { type: 'date' }, - metadata: { type: 'object' }, - started_at: { type: 'date' }, - status: { type: 'keyword' }, - total_document_count: { type: 'integer' }, - trigger_method: { type: 'keyword' }, - worker_hostname: { type: 'keyword' }, - }, - }, - name: '.elastic-connectors-sync-jobs-v1', - settings: defaultSettings, - }, -]; - -const createConnectorsIndex = async ( - client: ElasticsearchClient, - indexDefinition: IndexDefinition -) => { - try { - const { aliases, mappings, name: index, settings } = indexDefinition; - await client.indices.create({ - index, - mappings, - settings, - }); - await client.indices.updateAliases({ - actions: [ - { - add: { - aliases, - index, - is_hidden: true, - is_write_index: true, - }, - }, - ], - }); - } catch (error) { - if (isResourceAlreadyExistsException(error)) { - // We hit a race condition, do nothing - return; - } - return error; - } -}; - -export const setupConnectorsIndices = async (client: ElasticsearchClient) => { - const connectorsIndexResponse = await client.indices.get({ - index: `${CONNECTORS_INDEX}*`, - }); - for (const indexDefinition of indices) { - if (!connectorsIndexResponse[indexDefinition.name]) { - await createConnectorsIndex(client, indexDefinition); - } - // TODO handle migrations once we start migrating stuff - } -}; diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts index fb373ed440dce..5f9168bffe5e7 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.test.ts @@ -7,12 +7,10 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { CONNECTORS_INDEX } from '../..'; +import { CURRENT_CONNECTORS_INDEX } from '../..'; import { ConnectorStatus } from '../../../common/types/connectors'; import { ErrorCode } from '../../../common/types/error_codes'; -import { setupConnectorsIndices } from '../../index_management/setup_indices'; - import { fetchCrawlerByIndexName } from '../crawler/fetch_crawlers'; import { textAnalysisSettings } from '../indices/text_analysis'; @@ -20,10 +18,6 @@ import { addConnector } from './add_connector'; import { deleteConnectorById } from './delete_connector'; import { fetchConnectorByIndexName } from './fetch_connectors'; -jest.mock('../../index_management/setup_indices', () => ({ - setupConnectorsIndices: jest.fn(), -})); - jest.mock('./fetch_connectors', () => ({ fetchConnectorByIndexName: jest.fn() })); jest.mock('./delete_connector', () => ({ deleteConnectorById: jest.fn() })); jest.mock('../crawler/fetch_crawlers', () => ({ fetchCrawlerByIndexName: jest.fn() })); @@ -41,11 +35,6 @@ describe('addConnector lib function', () => { asInternalUser: {}, }; - const createConnectorsIndexExistsFn = - (connectorsIndexExists: boolean, defaultValue: boolean) => - ({ index }: { index: string }) => - index === CONNECTORS_INDEX ? connectorsIndexExists : defaultValue; - beforeEach(() => { jest.clearAllMocks(); }); @@ -68,9 +57,7 @@ describe('addConnector lib function', () => { it('should add connector', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation( - createConnectorsIndexExistsFn(true, false) - ); + mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => undefined); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); @@ -169,7 +156,7 @@ describe('addConnector lib function', () => { status: ConnectorStatus.CREATED, sync_now: false, }, - index: CONNECTORS_INDEX, + index: CURRENT_CONNECTORS_INDEX, refresh: 'wait_for', }); expect(mockClient.asCurrentUser.indices.create).toHaveBeenCalledWith({ @@ -181,9 +168,7 @@ describe('addConnector lib function', () => { it('should reject if index already exists', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation( - createConnectorsIndexExistsFn(true, true) - ); + mockClient.asCurrentUser.indices.exists.mockImplementation(() => true); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => undefined); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); @@ -200,9 +185,7 @@ describe('addConnector lib function', () => { it('should reject if connector already exists', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation( - createConnectorsIndexExistsFn(true, false) - ); + mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => true); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); @@ -219,9 +202,7 @@ describe('addConnector lib function', () => { it('should reject if crawler already exists', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation( - createConnectorsIndexExistsFn(true, false) - ); + mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => undefined); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => true); mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); @@ -238,9 +219,7 @@ describe('addConnector lib function', () => { it('should reject with index already exists if connector and index already exist', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation( - createConnectorsIndexExistsFn(true, true) - ); + mockClient.asCurrentUser.indices.exists.mockImplementation(() => true); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => true); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); @@ -257,9 +236,7 @@ describe('addConnector lib function', () => { it('should replace connector if deleteExistingConnector flag is true', async () => { mockClient.asCurrentUser.index.mockImplementation(() => ({ _id: 'fakeId' })); - mockClient.asCurrentUser.indices.exists.mockImplementation( - createConnectorsIndexExistsFn(true, false) - ); + mockClient.asCurrentUser.indices.exists.mockImplementation(() => false); (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => ({ id: 'connectorId' })); (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); @@ -360,7 +337,7 @@ describe('addConnector lib function', () => { status: ConnectorStatus.CREATED, sync_now: false, }, - index: CONNECTORS_INDEX, + index: CURRENT_CONNECTORS_INDEX, refresh: 'wait_for', }); expect(mockClient.asCurrentUser.indices.create).toHaveBeenCalledWith({ @@ -373,116 +350,4 @@ describe('addConnector lib function', () => { }, }); }); - - it('should create index if no connectors index exists', async () => { - mockClient.asCurrentUser.indices.exists.mockImplementation( - createConnectorsIndexExistsFn(false, false) - ); - (fetchConnectorByIndexName as jest.Mock).mockImplementation(() => false); - (fetchCrawlerByIndexName as jest.Mock).mockImplementation(() => undefined); - mockClient.asCurrentUser.indices.getMapping.mockImplementation(() => connectorsIndicesMapping); - await expect( - addConnector(mockClient as unknown as IScopedClusterClient, { - index_name: 'search-index_name', - is_native: false, - language: 'en', - }) - ).resolves.toEqual({ id: 'fakeId', index_name: 'search-index_name' }); - expect(setupConnectorsIndices as jest.Mock).toHaveBeenCalledWith(mockClient.asCurrentUser); - expect(mockClient.asCurrentUser.index).toHaveBeenCalledWith({ - document: { - api_key_id: null, - configuration: {}, - custom_scheduling: {}, - description: null, - error: null, - features: null, - filtering: [ - { - active: { - advanced_snippet: { - created_at: expect.any(String), - updated_at: expect.any(String), - value: {}, - }, - rules: [ - { - created_at: expect.any(String), - field: '_', - id: 'DEFAULT', - order: 0, - policy: 'include', - rule: 'regex', - updated_at: expect.any(String), - value: '.*', - }, - ], - validation: { - errors: [], - state: 'valid', - }, - }, - domain: 'DEFAULT', - draft: { - advanced_snippet: { - created_at: expect.any(String), - updated_at: expect.any(String), - value: {}, - }, - rules: [ - { - created_at: expect.any(String), - field: '_', - id: 'DEFAULT', - order: 0, - policy: 'include', - rule: 'regex', - updated_at: expect.any(String), - value: '.*', - }, - ], - validation: { - errors: [], - state: 'valid', - }, - }, - }, - ], - index_name: 'search-index_name', - is_native: false, - language: 'en', - last_access_control_sync_error: null, - last_access_control_sync_scheduled_at: null, - last_access_control_sync_status: null, - last_incremental_sync_scheduled_at: null, - last_seen: null, - last_sync_error: null, - last_sync_scheduled_at: null, - last_sync_status: null, - last_synced: null, - name: 'index_name', - pipeline: { - extract_binary_content: true, - name: 'ent-search-generic-ingestion', - reduce_whitespace: true, - run_ml_inference: false, - }, - scheduling: { - access_control: { enabled: false, interval: '0 0 0 * * ?' }, - full: { enabled: false, interval: '0 0 0 * * ?' }, - incremental: { enabled: false, interval: '0 0 0 * * ?' }, - }, - service_type: null, - status: ConnectorStatus.CREATED, - sync_now: false, - }, - index: CONNECTORS_INDEX, - refresh: 'wait_for', - }); - expect(mockClient.asCurrentUser.indices.create).toHaveBeenCalledWith({ - index: 'search-index_name', - mappings: {}, - settings: { ...textAnalysisSettings('en'), auto_expand_replicas: '0-3', number_of_shards: 2 }, - }); - }); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts index 455d3213c1d67..c3a7ebe26dc3f 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/add_connector.ts @@ -7,17 +7,14 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { CONNECTORS_INDEX, CONNECTORS_VERSION } from '../..'; +import { CURRENT_CONNECTORS_INDEX } from '../..'; import { ConnectorDocument } from '../../../common/types/connectors'; import { ErrorCode } from '../../../common/types/error_codes'; -import { - DefaultConnectorsPipelineMeta, - setupConnectorsIndices, -} from '../../index_management/setup_indices'; import { createConnectorDocument } from '../../utils/create_connector_document'; import { fetchCrawlerByIndexName } from '../crawler/fetch_crawlers'; import { createIndex } from '../indices/create_index'; +import { getDefaultPipeline } from '../pipelines/get_default_pipeline'; import { deleteConnectorById } from './delete_connector'; @@ -53,7 +50,7 @@ const createConnector = async ( const result = await client.asCurrentUser.index({ document, - index: CONNECTORS_INDEX, + index: CURRENT_CONNECTORS_INDEX, refresh: 'wait_for', }); await createIndex(client, document.index_name, language, false); @@ -71,31 +68,13 @@ export const addConnector = async ( service_type?: string; } ): Promise<{ id: string; index_name: string }> => { - const connectorsIndexExists = await client.asCurrentUser.indices.exists({ - index: CONNECTORS_INDEX, - }); - if (!connectorsIndexExists) { - await setupConnectorsIndices(client.asCurrentUser); - } - const connectorsIndicesMapping = await client.asCurrentUser.indices.getMapping({ - index: CONNECTORS_INDEX, - }); - const pipeline: DefaultConnectorsPipelineMeta = - connectorsIndicesMapping[`${CONNECTORS_INDEX}-v${CONNECTORS_VERSION}`]?.mappings?._meta - ?.pipeline; + const pipeline = await getDefaultPipeline(client); const document = createConnectorDocument({ indexName: input.index_name, isNative: input.is_native, language: input.language, - pipeline: pipeline - ? { - extract_binary_content: pipeline.default_extract_binary_content, - name: pipeline.default_name, - reduce_whitespace: pipeline.default_reduce_whitespace, - run_ml_inference: pipeline.default_run_ml_inference, - } - : null, + pipeline, serviceType: input.service_type ?? null, }); diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connector_index_names.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connector_index_names.ts index b7289978151a9..695a23139fbc6 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connector_index_names.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connector_index_names.ts @@ -5,16 +5,24 @@ * 2.0. */ +import { isIndexNotFoundException } from '@kbn/core-saved-objects-migration-server-internal'; import { IScopedClusterClient } from '@kbn/core/server'; import { CONNECTORS_INDEX } from '../..'; export async function fetchConnectorIndexNames(client: IScopedClusterClient): Promise { - const result = await client.asCurrentUser.search({ - _source: false, - fields: [{ field: 'index_name' }], - index: CONNECTORS_INDEX, - size: 10000, - }); - return (result?.hits.hits ?? []).map((field) => field.fields?.index_name[0] ?? ''); + try { + const result = await client.asCurrentUser.search({ + _source: false, + fields: [{ field: 'index_name' }], + index: CONNECTORS_INDEX, + size: 10000, + }); + return (result?.hits.hits ?? []).map((field) => field.fields?.index_name[0] ?? ''); + } catch (error) { + if (isIndexNotFoundException(error)) { + return []; + } + throw error; + } } diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connectors.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connectors.test.ts index 397369b5054ab..4196aad469d65 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connectors.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connectors.test.ts @@ -6,13 +6,28 @@ */ import { CONNECTORS_INDEX } from '../..'; -import { setupConnectorsIndices } from '../../index_management/setup_indices'; import { fetchConnectorById, fetchConnectorByIndexName, fetchConnectors } from './fetch_connectors'; -jest.mock('../../index_management/setup_indices', () => ({ - setupConnectorsIndices: jest.fn(), -})); +const indexNotFoundError = { + meta: { + body: { + error: { + type: 'index_not_found_exception', + }, + }, + }, +}; + +const otherError = { + meta: { + body: { + error: { + type: 'other_error', + }, + }, + }, +}; describe('fetchConnectors lib', () => { const mockClient = { @@ -46,43 +61,21 @@ describe('fetchConnectors lib', () => { index: CONNECTORS_INDEX, }); }); - it('should call setup connectors on index not found error', async () => { - mockClient.asCurrentUser.get.mockImplementationOnce(() => - Promise.reject({ - meta: { - body: { - error: { - type: 'index_not_found_exception', - }, - }, - }, - }) - ); + it('should return undefined on index not found error', async () => { + mockClient.asCurrentUser.get.mockImplementationOnce(() => Promise.reject(indexNotFoundError)); await expect(fetchConnectorById(mockClient as any, 'id')).resolves.toEqual(undefined); expect(mockClient.asCurrentUser.get).toHaveBeenCalledWith({ id: 'id', index: CONNECTORS_INDEX, }); - expect(setupConnectorsIndices as jest.Mock).toHaveBeenCalledWith(mockClient.asCurrentUser); }); - it('should not call setup connectors on other errors', async () => { - mockClient.asCurrentUser.get.mockImplementationOnce(() => - Promise.reject({ - meta: { - body: { - error: { - type: 'other error', - }, - }, - }, - }) - ); - await expect(fetchConnectorById(mockClient as any, 'id')).resolves.toEqual(undefined); + it('should throw on other errors', async () => { + mockClient.asCurrentUser.get.mockImplementationOnce(() => Promise.reject(otherError)); + await expect(fetchConnectorById(mockClient as any, 'id')).rejects.toEqual(otherError); expect(mockClient.asCurrentUser.get).toHaveBeenCalledWith({ id: 'id', index: CONNECTORS_INDEX, }); - expect(setupConnectorsIndices as jest.Mock).not.toHaveBeenCalled(); }); }); describe('fetch connector by name', () => { @@ -106,15 +99,9 @@ describe('fetchConnectors lib', () => { }, }); }); - it('should call setup connectors on index not found error', async () => { + it('should return undefined on index not found error', async () => { mockClient.asCurrentUser.search.mockImplementationOnce(() => - Promise.reject({ - meta: { - body: { - error: { type: 'index_not_found_exception' }, - }, - }, - }) + Promise.reject(indexNotFoundError) ); await expect(fetchConnectorByIndexName(mockClient as any, 'id')).resolves.toEqual(undefined); expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({ @@ -125,21 +112,10 @@ describe('fetchConnectors lib', () => { }, }, }); - expect(setupConnectorsIndices as jest.Mock).toHaveBeenCalledWith(mockClient.asCurrentUser); }); - it('should not call setup connectors on other errors', async () => { - mockClient.asCurrentUser.search.mockImplementationOnce(() => - Promise.reject({ - meta: { - body: { - error: { - type: 'other error', - }, - }, - }, - }) - ); - await expect(fetchConnectorByIndexName(mockClient as any, 'id')).resolves.toEqual(undefined); + it('should throw on other errors', async () => { + mockClient.asCurrentUser.search.mockImplementationOnce(() => Promise.reject(otherError)); + await expect(fetchConnectorByIndexName(mockClient as any, 'id')).rejects.toEqual(otherError); expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({ index: CONNECTORS_INDEX, query: { @@ -148,7 +124,6 @@ describe('fetchConnectors lib', () => { }, }, }); - expect(setupConnectorsIndices as jest.Mock).not.toHaveBeenCalled(); }); }); describe('fetch connectors', () => { @@ -197,15 +172,9 @@ describe('fetchConnectors lib', () => { }); expect(mockClient.asCurrentUser.search).toHaveBeenCalledTimes(3); }); - it('should call setup connectors on index not found error', async () => { + it('should return empty array on index not found error', async () => { mockClient.asCurrentUser.search.mockImplementationOnce(() => - Promise.reject({ - meta: { - body: { - error: { type: 'index_not_found_exception' }, - }, - }, - }) + Promise.reject(indexNotFoundError) ); await expect(fetchConnectors(mockClient as any)).resolves.toEqual([]); expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({ @@ -214,28 +183,16 @@ describe('fetchConnectors lib', () => { query: { match_all: {} }, size: 1000, }); - expect(setupConnectorsIndices as jest.Mock).toHaveBeenCalledWith(mockClient.asCurrentUser); }); - it('should not call setup connectors on other errors', async () => { - mockClient.asCurrentUser.search.mockImplementationOnce(() => - Promise.reject({ - meta: { - body: { - error: { - type: 'other error', - }, - }, - }, - }) - ); - await expect(fetchConnectors(mockClient as any)).resolves.toEqual([]); + it('should throw on other errors', async () => { + mockClient.asCurrentUser.search.mockImplementationOnce(() => Promise.reject(otherError)); + await expect(fetchConnectors(mockClient as any)).rejects.toEqual(otherError); expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({ from: 0, index: CONNECTORS_INDEX, query: { match_all: {} }, size: 1000, }); - expect(setupConnectorsIndices as jest.Mock).not.toHaveBeenCalled(); }); }); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connectors.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connectors.ts index 69c0e6e25b1a8..c1d8b834d0e15 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connectors.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_connectors.ts @@ -11,8 +11,6 @@ import { IScopedClusterClient } from '@kbn/core/server'; import { CONNECTORS_INDEX } from '../..'; import { Connector, ConnectorDocument } from '../../../common/types/connectors'; import { OptimisticConcurrency } from '../../../common/types/util_types'; -import { setupConnectorsIndices } from '../../index_management/setup_indices'; - import { isIndexNotFoundException } from '../../utils/identify_exceptions'; import { fetchAll } from '../fetch_all'; @@ -34,9 +32,9 @@ export const fetchConnectorById = async ( : undefined; } catch (error) { if (isIndexNotFoundException(error)) { - await setupConnectorsIndices(client.asCurrentUser); + return undefined; } - return undefined; + throw error; } }; @@ -57,9 +55,9 @@ export const fetchConnectorByIndexName = async ( return result; } catch (error) { if (isIndexNotFoundException(error)) { - await setupConnectorsIndices(client.asCurrentUser); + return undefined; } - return undefined; + throw error; } }; @@ -75,8 +73,8 @@ export const fetchConnectors = async ( return await fetchAll(client, CONNECTORS_INDEX, query); } catch (error) { if (isIndexNotFoundException(error)) { - await setupConnectorsIndices(client.asCurrentUser); + return []; } - return []; + throw error; } }; diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_sync_jobs.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_sync_jobs.test.ts index 5408ac4d4a9e7..651849e803c41 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_sync_jobs.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_sync_jobs.test.ts @@ -5,14 +5,8 @@ * 2.0. */ -import { setupConnectorsIndices } from '../../index_management/setup_indices'; - import { fetchSyncJobsByConnectorId } from './fetch_sync_jobs'; -jest.mock('../../index_management/setup_indices', () => ({ - setupConnectorsIndices: jest.fn(), -})); - describe('fetchSyncJobs lib', () => { const mockClient = { asCurrentUser: { @@ -71,7 +65,7 @@ describe('fetchSyncJobs lib', () => { }); expect(mockClient.asCurrentUser.search).not.toHaveBeenCalled(); }); - it('should call setup connectors on index not found error', async () => { + it('should return empty array on index not found error', async () => { mockClient.asCurrentUser.search.mockImplementationOnce(() => Promise.reject({ meta: { @@ -109,9 +103,8 @@ describe('fetchSyncJobs lib', () => { }, }, }); - expect(setupConnectorsIndices as jest.Mock).toHaveBeenCalledWith(mockClient.asCurrentUser); }); - it('should not call setup connectors on other errors', async () => { + it('should throw on other errors', async () => { mockClient.asCurrentUser.search.mockImplementationOnce(() => Promise.reject({ meta: { @@ -147,7 +140,6 @@ describe('fetchSyncJobs lib', () => { }, }, }); - expect(setupConnectorsIndices as jest.Mock).not.toHaveBeenCalled(); }); }); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_sync_jobs.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_sync_jobs.ts index 23d9bcc842d18..43f373712f753 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_sync_jobs.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/fetch_sync_jobs.ts @@ -12,7 +12,6 @@ import { ConnectorSyncJob, SyncJobType } from '../../../common/types/connectors' import { Paginate } from '../../../common/types/pagination'; import { isNotNullish } from '../../../common/utils/is_not_nullish'; -import { setupConnectorsIndices } from '../../index_management/setup_indices'; import { fetchWithPagination } from '../../utils/fetch_with_pagination'; import { isIndexNotFoundException } from '../../utils/identify_exceptions'; @@ -82,10 +81,8 @@ export const fetchSyncJobsByConnectorId = async ( }; } catch (error) { if (isIndexNotFoundException(error)) { - await setupConnectorsIndices(client.asCurrentUser); return defaultResult; - } else { - throw error; } + throw error; } }; diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts index 4e35acd1434b4..90d82c82aca93 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.test.ts @@ -7,7 +7,7 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX } from '../..'; +import { CONNECTORS_INDEX, CURRENT_CONNECTORS_JOB_INDEX } from '../..'; import { CONNECTORS_ACCESS_CONTROL_INDEX_PREFIX } from '../../../common/constants'; import { SyncJobType, SyncStatus, TriggerMethod } from '../../../common/types/connectors'; @@ -95,7 +95,7 @@ describe('startSync lib function', () => { trigger_method: TriggerMethod.ON_DEMAND, worker_hostname: null, }, - index: CONNECTORS_JOBS_INDEX, + index: CURRENT_CONNECTORS_JOB_INDEX, }); }); it('should start a full sync with service type, pipeline and nextSyncConfig', async () => { @@ -164,7 +164,7 @@ describe('startSync lib function', () => { trigger_method: TriggerMethod.ON_DEMAND, worker_hostname: null, }, - index: CONNECTORS_JOBS_INDEX, + index: CURRENT_CONNECTORS_JOB_INDEX, }); }); @@ -299,7 +299,7 @@ describe('startSync lib function', () => { trigger_method: TriggerMethod.ON_DEMAND, worker_hostname: null, }, - index: CONNECTORS_JOBS_INDEX, + index: CURRENT_CONNECTORS_JOB_INDEX, }); }); @@ -366,7 +366,7 @@ describe('startSync lib function', () => { trigger_method: TriggerMethod.ON_DEMAND, worker_hostname: null, }, - index: CONNECTORS_JOBS_INDEX, + index: CURRENT_CONNECTORS_JOB_INDEX, }); }); }); diff --git a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts index a3b2164c467a1..4c9ce9ffc162f 100644 --- a/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts +++ b/x-pack/plugins/enterprise_search/server/lib/connectors/start_sync.ts @@ -7,7 +7,7 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX } from '../..'; +import { CONNECTORS_INDEX, CURRENT_CONNECTORS_JOB_INDEX } from '../..'; import { isConfigEntry } from '../../../common/connectors/is_category_entry'; import { @@ -99,7 +99,7 @@ export const startConnectorSync = async ( trigger_method: TriggerMethod.ON_DEMAND, worker_hostname: null, }, - index: CONNECTORS_JOBS_INDEX, + index: CURRENT_CONNECTORS_JOB_INDEX, }); } else { throw new Error(ErrorCode.RESOURCE_NOT_FOUND); diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.ts index 95422eb7b96e8..4233f8abbeff1 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_index.ts @@ -12,6 +12,7 @@ import { CONNECTORS_JOBS_INDEX } from '../..'; import { ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE } from '../../../common/constants'; import { ConnectorSyncJobDocument, SyncStatus } from '../../../common/types/connectors'; import { ElasticsearchIndexWithIngestion } from '../../../common/types/indices'; +import { isIndexNotFoundException } from '../../utils/identify_exceptions'; import { fetchConnectorByIndexName } from '../connectors/fetch_connectors'; import { fetchCrawlerByIndexName } from '../crawler/fetch_crawlers'; @@ -21,29 +22,36 @@ const hasInProgressSyncs = async ( client: IScopedClusterClient, connectorId: string ): Promise<{ inProgress: boolean; pending: boolean }> => { - const syncs = await client.asCurrentUser.search({ - index: CONNECTORS_JOBS_INDEX, - query: { - bool: { - filter: [ - { term: { 'connector.id': connectorId } }, - { - dis_max: { - queries: [ - { term: { status: SyncStatus.IN_PROGRESS } }, - { term: { status: SyncStatus.PENDING } }, - ], + try { + const syncs = await client.asCurrentUser.search({ + index: CONNECTORS_JOBS_INDEX, + query: { + bool: { + filter: [ + { term: { 'connector.id': connectorId } }, + { + dis_max: { + queries: [ + { term: { status: SyncStatus.IN_PROGRESS } }, + { term: { status: SyncStatus.PENDING } }, + ], + }, }, - }, - ], + ], + }, }, - }, - }); - const inProgress = syncs.hits.hits.some( - (sync) => sync._source?.status === SyncStatus.IN_PROGRESS - ); - const pending = syncs.hits.hits.some((sync) => sync._source?.status === SyncStatus.PENDING); - return { inProgress, pending }; + }); + const inProgress = syncs.hits.hits.some( + (sync) => sync._source?.status === SyncStatus.IN_PROGRESS + ); + const pending = syncs.hits.hits.some((sync) => sync._source?.status === SyncStatus.PENDING); + return { inProgress, pending }; + } catch (error) { + if (isIndexNotFoundException(error)) { + return { inProgress: false, pending: false }; + } + throw error; + } }; export const fetchIndex = async ( diff --git a/x-pack/plugins/enterprise_search/server/lib/pipelines/get_default_pipeline.ts b/x-pack/plugins/enterprise_search/server/lib/pipelines/get_default_pipeline.ts index 0959b7e8cfa7f..c13ee2571b82b 100644 --- a/x-pack/plugins/enterprise_search/server/lib/pipelines/get_default_pipeline.ts +++ b/x-pack/plugins/enterprise_search/server/lib/pipelines/get_default_pipeline.ts @@ -10,24 +10,32 @@ import { IScopedClusterClient } from '@kbn/core/server'; import { CURRENT_CONNECTORS_INDEX } from '../..'; import { DEFAULT_PIPELINE_VALUES } from '../../../common/constants'; +import { DefaultConnectorsPipelineMeta } from '../../../common/constants'; import { IngestPipelineParams } from '../../../common/types/connectors'; -import { DefaultConnectorsPipelineMeta } from '../../index_management/setup_indices'; +import { isIndexNotFoundException } from '../../utils/identify_exceptions'; export const getDefaultPipeline = async ( client: IScopedClusterClient ): Promise => { - const mapping = await client.asCurrentUser.indices.getMapping({ - index: CURRENT_CONNECTORS_INDEX, - }); - const meta: DefaultConnectorsPipelineMeta | undefined = - mapping[CURRENT_CONNECTORS_INDEX]?.mappings._meta?.pipeline; - const mappedMapping: IngestPipelineParams = meta - ? { - extract_binary_content: meta.default_extract_binary_content, - name: meta.default_name, - reduce_whitespace: meta.default_reduce_whitespace, - run_ml_inference: meta.default_run_ml_inference, - } - : DEFAULT_PIPELINE_VALUES; - return mappedMapping; + try { + const mapping = await client.asCurrentUser.indices.getMapping({ + index: CURRENT_CONNECTORS_INDEX, + }); + const meta: DefaultConnectorsPipelineMeta | undefined = + mapping[CURRENT_CONNECTORS_INDEX]?.mappings._meta?.pipeline; + const mappedMapping: IngestPipelineParams = meta + ? { + extract_binary_content: meta.default_extract_binary_content, + name: meta.default_name, + reduce_whitespace: meta.default_reduce_whitespace, + run_ml_inference: meta.default_run_ml_inference, + } + : DEFAULT_PIPELINE_VALUES; + return mappedMapping; + } catch (error) { + if (isIndexNotFoundException(error)) { + return DEFAULT_PIPELINE_VALUES; + } + throw error; + } }; diff --git a/x-pack/plugins/enterprise_search/server/lib/pipelines/update_default_pipeline.ts b/x-pack/plugins/enterprise_search/server/lib/pipelines/update_default_pipeline.ts index 8dfaf0ac8ba42..060c0edc88316 100644 --- a/x-pack/plugins/enterprise_search/server/lib/pipelines/update_default_pipeline.ts +++ b/x-pack/plugins/enterprise_search/server/lib/pipelines/update_default_pipeline.ts @@ -9,12 +9,8 @@ import { IScopedClusterClient } from '@kbn/core/server'; import { CURRENT_CONNECTORS_INDEX } from '../..'; +import { DefaultConnectorsPipelineMeta } from '../../../common/constants'; import { IngestPipelineParams } from '../../../common/types/connectors'; -import { - DefaultConnectorsPipelineMeta, - setupConnectorsIndices, -} from '../../index_management/setup_indices'; -import { isIndexNotFoundException } from '../../utils/identify_exceptions'; export const updateDefaultPipeline = async ( client: IScopedClusterClient, @@ -35,8 +31,7 @@ export const updateDefaultPipeline = async ( index: CURRENT_CONNECTORS_INDEX, }); } catch (error) { - if (isIndexNotFoundException(error)) { - setupConnectorsIndices(client.asCurrentUser); - } + // TODO: Throw error saying you have to index a connector first + throw error; } }; diff --git a/x-pack/plugins/enterprise_search/server/lib/stats/get_sync_jobs.ts b/x-pack/plugins/enterprise_search/server/lib/stats/get_sync_jobs.ts index 4e428c797eca5..a19315507bf4c 100644 --- a/x-pack/plugins/enterprise_search/server/lib/stats/get_sync_jobs.ts +++ b/x-pack/plugins/enterprise_search/server/lib/stats/get_sync_jobs.ts @@ -13,125 +13,140 @@ import { CONNECTORS_INDEX, CONNECTORS_JOBS_INDEX } from '../..'; import { SyncJobsStats } from '../../../common/stats'; import { ConnectorStatus, SyncStatus } from '../../../common/types/connectors'; +import { isIndexNotFoundException } from '../../utils/identify_exceptions'; export const fetchSyncJobsStats = async (client: IScopedClusterClient): Promise => { - const connectorIdsResult = await client.asCurrentUser.search({ - index: CONNECTORS_INDEX, - scroll: '10s', - stored_fields: [], - }); - const ids = connectorIdsResult.hits.hits.map((hit) => hit._id); - const orphanedJobsCountResponse = await client.asCurrentUser.count({ - index: CONNECTORS_JOBS_INDEX, - query: { - bool: { - must_not: [ - { - terms: { - 'connector.id': ids, + try { + const connectorIdsResult = await client.asCurrentUser.search({ + index: CONNECTORS_INDEX, + scroll: '10s', + stored_fields: [], + }); + const ids = connectorIdsResult.hits.hits.map((hit) => hit._id); + const orphanedJobsCountResponse = await client.asCurrentUser.count({ + index: CONNECTORS_JOBS_INDEX, + query: { + bool: { + must_not: [ + { + terms: { + 'connector.id': ids, + }, }, - }, - ], + ], + }, }, - }, - }); + }); - const inProgressJobsCountResponse = await client.asCurrentUser.count({ - index: CONNECTORS_JOBS_INDEX, - query: { - term: { - status: SyncStatus.IN_PROGRESS, + const inProgressJobsCountResponse = await client.asCurrentUser.count({ + index: CONNECTORS_JOBS_INDEX, + query: { + term: { + status: SyncStatus.IN_PROGRESS, + }, }, - }, - }); + }); - const idleJobsCountResponse = await client.asCurrentUser.count({ - index: CONNECTORS_JOBS_INDEX, - query: { - bool: { - filter: [ - { - term: { - status: SyncStatus.IN_PROGRESS, + const idleJobsCountResponse = await client.asCurrentUser.count({ + index: CONNECTORS_JOBS_INDEX, + query: { + bool: { + filter: [ + { + term: { + status: SyncStatus.IN_PROGRESS, + }, }, - }, - { - range: { - last_seen: { - lt: moment().subtract(1, 'minute').toISOString(), + { + range: { + last_seen: { + lt: moment().subtract(1, 'minute').toISOString(), + }, }, }, - }, - ], + ], + }, }, - }, - }); + }); - const errorResponse = await client.asCurrentUser.count({ - index: CONNECTORS_INDEX, - query: { - term: { - last_sync_status: SyncStatus.ERROR, + const errorResponse = await client.asCurrentUser.count({ + index: CONNECTORS_INDEX, + query: { + term: { + last_sync_status: SyncStatus.ERROR, + }, }, - }, - }); + }); - const connectedResponse = await client.asCurrentUser.count({ - index: CONNECTORS_INDEX, - query: { - bool: { - filter: [ - { - term: { - status: ConnectorStatus.CONNECTED, + const connectedResponse = await client.asCurrentUser.count({ + index: CONNECTORS_INDEX, + query: { + bool: { + filter: [ + { + term: { + status: ConnectorStatus.CONNECTED, + }, }, - }, - { - range: { - last_seen: { - gte: moment().subtract(30, 'minutes').toISOString(), + { + range: { + last_seen: { + gte: moment().subtract(30, 'minutes').toISOString(), + }, }, }, - }, - ], + ], + }, }, - }, - }); + }); - const incompleteResponse = await client.asCurrentUser.count({ - index: CONNECTORS_INDEX, - query: { - bool: { - should: [ - { - bool: { - must_not: { - terms: { - status: [ConnectorStatus.CONNECTED, ConnectorStatus.ERROR], + const incompleteResponse = await client.asCurrentUser.count({ + index: CONNECTORS_INDEX, + query: { + bool: { + should: [ + { + bool: { + must_not: { + terms: { + status: [ConnectorStatus.CONNECTED, ConnectorStatus.ERROR], + }, }, }, }, - }, - { - range: { - last_seen: { - lt: moment().subtract(30, 'minutes').toISOString(), + { + range: { + last_seen: { + lt: moment().subtract(30, 'minutes').toISOString(), + }, }, }, - }, - ], + ], + }, }, - }, - }); + }); - const response = { - connected: connectedResponse.count, - errors: errorResponse.count, - idle: idleJobsCountResponse.count, - in_progress: inProgressJobsCountResponse.count, - incomplete: incompleteResponse.count, - orphaned_jobs: orphanedJobsCountResponse.count, - }; + const response = { + connected: connectedResponse.count, + errors: errorResponse.count, + idle: idleJobsCountResponse.count, + in_progress: inProgressJobsCountResponse.count, + incomplete: incompleteResponse.count, + orphaned_jobs: orphanedJobsCountResponse.count, + }; - return response; + return response; + } catch (error) { + if (isIndexNotFoundException(error)) { + return { + connected: 0, + errors: 0, + idle: 0, + in_progress: 0, + incomplete: 0, + orphaned_jobs: 0, + }; + } + throw error; + } }; From 5d5c10a320a7cc6b9f67bd59068e25c7cdca14c2 Mon Sep 17 00:00:00 2001 From: Gerard Soldevila Date: Wed, 12 Jul 2023 13:38:37 +0200 Subject: [PATCH 62/97] [Migrations - v2] Allow for 1 byte size variation in es_response_too_large (#161626) ## Summary Fixes https://github.com/elastic/kibana/issues/160994 There must be some randomness factor that causes the response payload size to have a 1 byte size variation, as observed in the `es_response_too_large` error. This PR relaxes the constraint and accepts a `es_response_too_large` error with either 3184 or 3185 bytes. --- .../migrations/group3/actions/actions.test.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions.test.ts index bffd4bb616856..3800bfc1184ba 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/actions/actions.test.ts @@ -1117,8 +1117,7 @@ describe('migration actions', () => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/160994 - describe.skip('readWithPit', () => { + describe('readWithPit', () => { it('requests documents from an index using given PIT', async () => { const openPitTask = openPit({ client, index: 'existing_index_with_docs' }); const pitResponse = (await openPitTask()) as Either.Right; @@ -1297,7 +1296,12 @@ describe('migration actions', () => { const leftResponse = (await readWithPitTask()) as Either.Left; expect(leftResponse.left.type).toBe('es_response_too_large'); - expect(leftResponse.left.contentLength).toBe(3184); + // ES response contains a field that indicates how long it took ES to get the response, e.g.: "took": 7 + // if ES takes more than 9ms, the payload will be 1 byte bigger. + // see https://github.com/elastic/kibana/issues/160994 + // Thus, the statements below account for response times up to 99ms + expect(leftResponse.left.contentLength).toBeGreaterThanOrEqual(3184); + expect(leftResponse.left.contentLength).toBeLessThanOrEqual(3185); }); it('rejects if PIT does not exist', async () => { From a78c7b02b3b825826f39289e91e545ee6f4a67d9 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 12 Jul 2023 13:53:41 +0200 Subject: [PATCH 63/97] [Synthetics] Fixes dom warnings for p > div (#161744) --- .../monitors_page/overview/overview/metric_item.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx index 6489515b83b50..2c0885c7d6258 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx @@ -139,13 +139,14 @@ export const MetricItem = ({ justifyContent="flexEnd" // empty title to prevent default title from showing title="" + component="span" > - + {i18n.translate('xpack.synthetics.overview.duration.label', { defaultMessage: 'Duration', })} - + Date: Wed, 12 Jul 2023 08:25:28 -0400 Subject: [PATCH 64/97] [Fleet] Test disabled API in serverless (#161688) --- x-pack/plugins/fleet/server/errors/index.ts | 4 +- .../server/routes/fleet_proxies/handler.ts | 4 +- .../test_suites/observability/fleet.ts | 52 +++++++++++++++++++ .../test_suites/observability/index.ts | 1 + .../test_suites/security/fleet.ts | 52 +++++++++++++++++++ .../test_suites/security/index.ts | 1 + 6 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/fleet.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/fleet.ts diff --git a/x-pack/plugins/fleet/server/errors/index.ts b/x-pack/plugins/fleet/server/errors/index.ts index bfab916d5a171..0b2c6b0fc5e93 100644 --- a/x-pack/plugins/fleet/server/errors/index.ts +++ b/x-pack/plugins/fleet/server/errors/index.ts @@ -77,8 +77,8 @@ export class OutputInvalidError extends FleetError {} export class OutputLicenceError extends FleetError {} export class DownloadSourceError extends FleetError {} -export class FleetServerHostUnauthorizedError extends FleetError {} -export class FleetProxyUnauthorizedError extends FleetError {} +export class FleetServerHostUnauthorizedError extends FleetUnauthorizedError {} +export class FleetProxyUnauthorizedError extends FleetUnauthorizedError {} export class ArtifactsClientError extends FleetError {} export class ArtifactsClientAccessDeniedError extends FleetError { diff --git a/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts b/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts index a77eba8a9a28e..e509dd1f8cd5d 100644 --- a/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts +++ b/x-pack/plugins/fleet/server/routes/fleet_proxies/handler.ts @@ -22,7 +22,7 @@ import { updateFleetProxy, getFleetProxyRelatedSavedObjects, } from '../../services/fleet_proxies'; -import { defaultFleetErrorHandler } from '../../errors'; +import { defaultFleetErrorHandler, FleetProxyUnauthorizedError } from '../../errors'; import type { GetOneFleetProxyRequestSchema, PostFleetProxyRequestSchema, @@ -68,7 +68,7 @@ async function bumpRelatedPolicies( function checkProxiesAvailable() { if (appContextService.getConfig()?.internal?.disableProxies) { - throw new Error('Proxies are not available'); + throw new FleetProxyUnauthorizedError('Proxies write APIs are disabled'); } } diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/fleet.ts b/x-pack/test_serverless/api_integration/test_suites/observability/fleet.ts new file mode 100644 index 0000000000000..06fbe54ca4410 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/observability/fleet.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from 'expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const svlCommonApi = getService('svlCommonApi'); + const supertest = getService('supertest'); + + describe('fleet', function () { + it('rejects request to create a new fleet server hosts', async () => { + const { body, status } = await supertest + .post('/api/fleet/fleet_server_hosts') + .set(svlCommonApi.getCommonRequestHeader()) + .send({ + name: 'test', + host_urls: ['https://localhost:8220'], + }); + + // in a non-serverless environment this would succeed with a 200 + expect(body).toEqual({ + statusCode: 403, + error: 'Forbidden', + message: 'Fleet server host write APIs are disabled', + }); + expect(status).toBe(403); + }); + + it('rejects request to create a new proxy', async () => { + const { body, status } = await supertest + .post('/api/fleet/proxies') + .set(svlCommonApi.getCommonRequestHeader()) + .send({ + name: 'test', + url: 'https://localhost:8220', + }); + + // in a non-serverless environment this would succeed with a 200 + expect(body).toEqual({ + statusCode: 403, + error: 'Forbidden', + message: 'Proxies write APIs are disabled', + }); + expect(status).toBe(403); + }); + }); +} diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/index.ts b/x-pack/test_serverless/api_integration/test_suites/observability/index.ts index 1020ebc74d551..ad140860f1963 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/index.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/index.ts @@ -9,6 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('serverless observability API', function () { + loadTestFile(require.resolve('./fleet')); loadTestFile(require.resolve('./snapshot_telemetry')); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/security/fleet.ts b/x-pack/test_serverless/api_integration/test_suites/security/fleet.ts new file mode 100644 index 0000000000000..06fbe54ca4410 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/security/fleet.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from 'expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const svlCommonApi = getService('svlCommonApi'); + const supertest = getService('supertest'); + + describe('fleet', function () { + it('rejects request to create a new fleet server hosts', async () => { + const { body, status } = await supertest + .post('/api/fleet/fleet_server_hosts') + .set(svlCommonApi.getCommonRequestHeader()) + .send({ + name: 'test', + host_urls: ['https://localhost:8220'], + }); + + // in a non-serverless environment this would succeed with a 200 + expect(body).toEqual({ + statusCode: 403, + error: 'Forbidden', + message: 'Fleet server host write APIs are disabled', + }); + expect(status).toBe(403); + }); + + it('rejects request to create a new proxy', async () => { + const { body, status } = await supertest + .post('/api/fleet/proxies') + .set(svlCommonApi.getCommonRequestHeader()) + .send({ + name: 'test', + url: 'https://localhost:8220', + }); + + // in a non-serverless environment this would succeed with a 200 + expect(body).toEqual({ + statusCode: 403, + error: 'Forbidden', + message: 'Proxies write APIs are disabled', + }); + expect(status).toBe(403); + }); + }); +} diff --git a/x-pack/test_serverless/api_integration/test_suites/security/index.ts b/x-pack/test_serverless/api_integration/test_suites/security/index.ts index 9dc97ea8a9b57..a57d4446e4b9b 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/index.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/index.ts @@ -9,6 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('serverless security API', function () { + loadTestFile(require.resolve('./fleet')); loadTestFile(require.resolve('./snapshot_telemetry')); }); } From 30fa4db8b5c8d8e14e8929e5529ca3fdda302613 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:38:46 +0200 Subject: [PATCH 65/97] [Fleet] add status telemetry to agents_per_version (#161731) ## Summary Closes https://github.com/elastic/ingest-dev/issues/1491 Querying agent statuses per version to add to telemetry. How to test locally: - enroll a few different version of agents - wait up to 1h to see the telemetry task triggered - check debug logs to see that the agents per version telemetry contains the status information ``` [2023-07-12T11:00:45.172+02:00][DEBUG][plugins.fleet] Agents per version telemetry: [{"version":"8.7.1","count":4,"healthy":4,"unhealthy":0,"updating":0,"inactive":0,"unenrolled":0,"offline":0},{"version":"8.2.1","count":3,"healthy":3,"unhealthy":0,"updating":0,"inactive":0,"unenrolled":0,"offline":0},{"version":"8.2.0","count":2,"healthy":0,"unhealthy":0,"updating":0,"inactive":0,"unenrolled":0,"offline":2}] ``` ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../server/collectors/agent_collectors.ts | 59 ++++++++++++++++--- .../fleet/server/collectors/register.ts | 2 +- .../fleet_usage_telemetry.test.ts | 22 ++++++- .../services/telemetry/fleet_usages_schema.ts | 36 +++++++++++ 4 files changed, 108 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/fleet/server/collectors/agent_collectors.ts b/x-pack/plugins/fleet/server/collectors/agent_collectors.ts index 8030b55a6a9fd..585e328f12e16 100644 --- a/x-pack/plugins/fleet/server/collectors/agent_collectors.ts +++ b/x-pack/plugins/fleet/server/collectors/agent_collectors.ts @@ -10,18 +10,22 @@ import type { SavedObjectsClient, ElasticsearchClient } from '@kbn/core/server'; import { AGENTS_INDEX } from '../../common'; import * as AgentService from '../services/agents'; import { appContextService } from '../services'; +import { getAgentStatusForAgentPolicy } from '../services/agents'; -export interface AgentUsage { - total_enrolled: number; +export interface AgentStatus { healthy: number; unhealthy: number; offline: number; inactive: number; unenrolled: number; - total_all_statuses: number; updating: number; } +export interface AgentUsage extends AgentStatus { + total_enrolled: number; + total_all_statuses: number; +} + export const getAgentUsage = async ( soClient?: SavedObjectsClient, esClient?: ElasticsearchClient @@ -55,10 +59,12 @@ export const getAgentUsage = async ( }; export interface AgentData { - agents_per_version: Array<{ - version: string; - count: number; - }>; + agents_per_version: Array< + { + version: string; + count: number; + } & AgentStatus + >; agent_checkin_status: { error: number; degraded: number; @@ -74,6 +80,7 @@ const DEFAULT_AGENT_DATA = { export const getAgentData = async ( esClient: ElasticsearchClient, + soClient: SavedObjectsClient, abortController: AbortController ): Promise => { try { @@ -115,8 +122,44 @@ export const getAgentData = async ( { signal: abortController.signal } ); const agentsPerVersion = ((response?.aggregations?.versions as any).buckets ?? []).map( - (bucket: any) => ({ version: bucket.key, count: bucket.doc_count }) + (bucket: any) => ({ + version: bucket.key, + count: bucket.doc_count, + healthy: 0, + unhealthy: 0, + updating: 0, + inactive: 0, + unenrolled: 0, + offline: 0, + }) ); + + const getAgentStatusesPerVersion = async (version: string) => { + return await getAgentStatusForAgentPolicy( + esClient, + soClient, + undefined, + `agent.version:${version}` + ); + }; + + for (const agent of agentsPerVersion) { + const { + inactive, + online: healthy, + error: unhealthy, + updating, + offline, + unenrolled, + } = await getAgentStatusesPerVersion(agent.version); + agent.healthy = healthy; + agent.unhealthy = unhealthy; + agent.updating = updating; + agent.inactive = inactive; + agent.unenrolled = unenrolled; + agent.offline = offline; + } + const statuses = transformLastCheckinStatusBuckets(response); const agentsPerPolicy = ((response?.aggregations?.policies as any).buckets ?? []).map( diff --git a/x-pack/plugins/fleet/server/collectors/register.ts b/x-pack/plugins/fleet/server/collectors/register.ts index d59298e835fa6..901a049df8d73 100644 --- a/x-pack/plugins/fleet/server/collectors/register.ts +++ b/x-pack/plugins/fleet/server/collectors/register.ts @@ -60,7 +60,7 @@ export const fetchFleetUsage = async ( agents: await getAgentUsage(soClient, esClient), fleet_server: await getFleetServerUsage(soClient, esClient), packages: await getPackageUsage(soClient), - ...(await getAgentData(esClient, abortController)), + ...(await getAgentData(esClient, soClient, abortController)), fleet_server_config: await getFleetServerConfig(soClient), agent_policies: await getAgentPoliciesUsage(soClient), ...(await getPanicLogsLastHour(esClient)), diff --git a/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts b/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts index 8d29d362125e3..e95a6fce722a0 100644 --- a/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts +++ b/x-pack/plugins/fleet/server/integration_tests/fleet_usage_telemetry.test.ts @@ -351,8 +351,26 @@ describe('fleet usage telemetry', () => { }, packages: [], agents_per_version: [ - { version: '8.5.1', count: 1 }, - { version: '8.6.0', count: 1 }, + { + version: '8.5.1', + count: 1, + healthy: 0, + inactive: 0, + offline: 1, + unenrolled: 1, + unhealthy: 0, + updating: 0, + }, + { + version: '8.6.0', + count: 1, + healthy: 0, + inactive: 0, + offline: 1, + unenrolled: 0, + unhealthy: 0, + updating: 0, + }, ], agent_checkin_status: { error: 1, degraded: 1 }, agents_per_policy: [2], diff --git a/x-pack/plugins/fleet/server/services/telemetry/fleet_usages_schema.ts b/x-pack/plugins/fleet/server/services/telemetry/fleet_usages_schema.ts index d92628f5e2971..faf963798768b 100644 --- a/x-pack/plugins/fleet/server/services/telemetry/fleet_usages_schema.ts +++ b/x-pack/plugins/fleet/server/services/telemetry/fleet_usages_schema.ts @@ -22,6 +22,42 @@ export const fleetAgentsSchema: RootSchema = { description: 'Number of agents enrolled that use this version', }, }, + healthy: { + type: 'long', + _meta: { + description: 'The total number of enrolled agents in a healthy state', + }, + }, + unhealthy: { + type: 'long', + _meta: { + description: 'The total number of enrolled agents in an unhealthy state', + }, + }, + updating: { + type: 'long', + _meta: { + description: 'The total number of enrolled agents in an updating state', + }, + }, + offline: { + type: 'long', + _meta: { + description: 'The total number of enrolled agents currently offline', + }, + }, + inactive: { + type: 'long', + _meta: { + description: 'The total number of enrolled agents currently inactive', + }, + }, + unenrolled: { + type: 'long', + _meta: { + description: 'The total number of unenrolled agents', + }, + }, }, }, }; From 3827dde90a552e15f22098a0e72122d3ad94d135 Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Wed, 12 Jul 2023 14:40:53 +0200 Subject: [PATCH 66/97] Security/tests/flaky group 4 (#161571) ## Summary Unskipping after running through flaky test runner 100 times: https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2599 Main ticket: https://github.com/elastic/kibana/issues/161531 Resolving #159499 Resolving #158905 Resolving #156088 Resolving #160297 --- .../group4/telemetry/usage_collector/detection_rules.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts index e0e0478c6ad0f..2f8f24a1ad2de 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts @@ -67,8 +67,7 @@ export default ({ getService }: FtrProviderContext) => { await deleteAllEventLogExecutionEvents(es, log); }); - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/160297 - describe.skip('"kql" rule type', () => { + describe('"kql" rule type', () => { it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "disabled"/"in-active" rule that does not have any actions', async () => { const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false); await createRule(supertest, log, rule); @@ -290,8 +289,7 @@ export default ({ getService }: FtrProviderContext) => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/156088 - describe.skip('"eql" rule type', () => { + describe('"eql" rule type', () => { it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "disabled"/"in-active" rule that does not have any actions', async () => { const rule = getEqlRuleForSignalTesting(['telemetry'], 'rule-1', false); await createRule(supertest, log, rule); From 19f00ec3d7a613f428d17059d838c801b3a80f6d Mon Sep 17 00:00:00 2001 From: Sid Date: Wed, 12 Jul 2023 14:59:09 +0200 Subject: [PATCH 67/97] Display user roles on user profile page (#161375) Closes https://github.com/elastic/kibana/issues/159566 ## Summary Adds a new section in the profile bar that highlights the assigned roles of the current user. The roles are rendered using the EUI Badges and if there are more roles than one, then the section only renders the first one while the rest are rendered in a Popover. ## Old UI image ## New UI #### For a user with a single role: image #### For a user with more than one role Show helper text and a button that opens a popover on click image #### Popover for users with long role names Setting the badge group max width to 200px (arbitrary for now) allows truncation of the role badges image --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../user_profile/user_profile.test.tsx | 62 ++++++++++ .../user_profile/user_profile.tsx | 116 ++++++++++++++++-- 2 files changed, 168 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx b/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx index 7a7839ef6e6db..b5748a16d1e43 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile.test.tsx @@ -395,4 +395,66 @@ describe('useUserProfileForm', () => { }); }); }); + + describe('User roles section', () => { + it('should display the user roles', () => { + const data: UserProfileData = {}; + + const nonCloudUser = mockAuthenticatedUser({ elastic_cloud_user: false }); + coreStart.settings.client.get.mockReturnValue(false); + coreStart.settings.client.isOverridden.mockReturnValue(true); + + const testWrapper = mount( + + + + ); + expect(testWrapper.exists('span[data-test-subj="userRoles"]')).toBeTruthy(); + + expect(testWrapper.exists('EuiButtonEmpty[data-test-subj="userRolesExpand"]')).toBeFalsy(); + expect(testWrapper.exists('EuiBadgeGroup[data-test-subj="remainingRoles"]')).toBeFalsy(); + }); + + it('should display a popover for users with more than one role', () => { + const data: UserProfileData = {}; + + const nonCloudUser = mockAuthenticatedUser({ elastic_cloud_user: false }); + coreStart.settings.client.get.mockReturnValue(false); + coreStart.settings.client.isOverridden.mockReturnValue(true); + + nonCloudUser.roles = [...nonCloudUser.roles, 'user-role-1', 'user-role-2']; + const testWrapper = mount( + + + + ); + + const extraRoles = nonCloudUser.roles.splice(1); + + const userRolesExpandButton = testWrapper.find( + 'EuiButtonEmpty[data-test-subj="userRolesExpand"]' + ); + + expect(userRolesExpandButton).toBeTruthy(); + expect(userRolesExpandButton.text()).toEqual(`+${extraRoles.length} more`); + }); + }); }); diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx b/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx index 0ffa627ac1a3f..fd7de9a7047f3 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx @@ -6,6 +6,8 @@ */ import { + EuiBadge, + EuiBadgeGroup, EuiButton, EuiButtonEmpty, EuiButtonGroup, @@ -21,6 +23,7 @@ import { EuiKeyPadMenu, EuiKeyPadMenuItem, EuiPageTemplate_Deprecated as EuiPageTemplate, + EuiPopover, EuiSpacer, EuiText, useEuiTheme, @@ -67,6 +70,20 @@ export interface UserProfileProps { }; } +export interface UserDetailsEditorProps { + user: AuthenticatedUser; +} + +export interface UserSettingsEditorProps { + formik: ReturnType; + isThemeOverridden: boolean; + isOverriddenThemeDarkMode: boolean; +} + +export interface UserRoleProps { + user: AuthenticatedUser; +} + export interface UserProfileFormValues { user: { full_name: string; @@ -85,7 +102,7 @@ export interface UserProfileFormValues { avatarType: 'initials' | 'image'; } -function UserDetailsEditor({ user }: { user: AuthenticatedUser }) { +const UserDetailsEditor: FunctionComponent = ({ user }) => { const { services } = useKibana(); const canChangeDetails = canUserChangeDetails(user, services.application.capabilities); @@ -142,17 +159,13 @@ function UserDetailsEditor({ user }: { user: AuthenticatedUser }) { ); -} +}; -function UserSettingsEditor({ +const UserSettingsEditor: FunctionComponent = ({ formik, isThemeOverridden, isOverriddenThemeDarkMode, -}: { - formik: ReturnType; - isThemeOverridden: boolean; - isOverriddenThemeDarkMode: boolean; -}) { +}) => { if (!formik.values.data) { return null; } @@ -262,7 +275,7 @@ function UserSettingsEditor({ ); -} +}; function UserAvatarEditor({ user, @@ -557,6 +570,68 @@ function UserPasswordEditor({ ); } +const UserRoles: FunctionComponent = ({ user }) => { + const { euiTheme } = useEuiTheme(); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + const onButtonClick = () => setIsPopoverOpen((isOpen) => !isOpen); + const closePopover = () => setIsPopoverOpen(false); + + const [firstRole] = user.roles; + const remainingRoles = user.roles.slice(1); + + const renderMoreRoles = () => { + const button = ( + + + + ); + return ( + + + {remainingRoles.map((role) => ( + + {role} + + ))} + + + ); + }; + + return ( + <> +

+ + {firstRole} + +
+ {remainingRoles.length ? renderMoreRoles() : null} + + ); +}; + export const UserProfile: FunctionComponent = ({ user, data }) => { const { euiTheme } = useEuiTheme(); const { services } = useKibana(); @@ -581,7 +656,7 @@ export const UserProfile: FunctionComponent = ({ user, data }) defaultMessage="Username" /> ), - description: user.username as string | undefined, + description: user.username as string | undefined | JSX.Element, helpText: ( = ({ user, data }) }); } + rightSideItems.push({ + title: ( + + ), + description: , + helpText: ( + + ), + testSubj: 'userRoles', + }); + return ( <> From c031900036b320dff64aebe14c0bf0ec9001ae84 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Wed, 12 Jul 2023 09:21:43 -0400 Subject: [PATCH 68/97] [Fleet] Fix dupplicate unhealthy callout (#161755) --- .../fleet/sections/agents/agent_list_page/index.tsx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx index bfb728c792a93..123fdfad5543e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx @@ -529,17 +529,6 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { )} - {/* TODO serverless agent soft limit */} - {showUnhealthyCallout && ( - <> - {cloud?.deploymentUrl ? ( - - ) : ( - - )} - - - )} {/* Search and filter bar */} Date: Wed, 12 Jul 2023 15:44:01 +0200 Subject: [PATCH 69/97] [Synthetics] Fix type warning (#161745) --- .../synthetics_overview_status.ts | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts index f89688b36fee4..d5f6fa883e4b5 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/synthetics_overview_status.ts @@ -10,20 +10,24 @@ import { ObserverCodec } from '../ping/observer'; import { ErrorStateCodec } from '../ping/error_state'; import { AgentType, MonitorType, PingErrorType, UrlType } from '..'; -export const OverviewPingCode = t.interface({ - '@timestamp': t.string, - summary: t.partial({ - down: t.number, - up: t.number, +export const OverviewPingCodec = t.intersection([ + t.interface({ + '@timestamp': t.string, + summary: t.partial({ + down: t.number, + up: t.number, + }), + monitor: MonitorType, + observer: ObserverCodec, + config_id: t.string, + agent: AgentType, + url: UrlType, + state: ErrorStateCodec, }), - monitor: MonitorType, - observer: ObserverCodec, - config_id: t.string, - error: PingErrorType, - agent: AgentType, - url: UrlType, - state: ErrorStateCodec, -}); + t.partial({ + error: PingErrorType, + }), +]); export const OverviewStatusMetaDataCodec = t.interface({ monitorQueryId: t.string, @@ -31,7 +35,7 @@ export const OverviewStatusMetaDataCodec = t.interface({ status: t.string, location: t.string, timestamp: t.string, - ping: OverviewPingCode, + ping: OverviewPingCodec, }); export const OverviewPendingStatusMetaDataCodec = t.intersection([ @@ -43,7 +47,7 @@ export const OverviewPendingStatusMetaDataCodec = t.intersection([ }), t.partial({ timestamp: t.string, - ping: OverviewPingCode, + ping: OverviewPingCodec, }), ]); @@ -70,7 +74,7 @@ export const OverviewStatusStateCodec = t.intersection([ }), ]); -export type OverviewPing = t.TypeOf; +export type OverviewPing = t.TypeOf; export type OverviewStatus = t.TypeOf; export type OverviewStatusState = t.TypeOf; export type OverviewStatusMetaData = t.TypeOf; From 11856ab1d24d99b2ba1d07997705ecb37cd4703a Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Wed, 12 Jul 2023 15:56:20 +0200 Subject: [PATCH 70/97] [Security Solution] Unskipping Cypress local storage test (#161655) --- .../timelines/local_storage.cy.ts | 26 +++++++++---------- .../cypress/screens/timeline.ts | 7 +++-- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/local_storage.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/local_storage.cy.ts index 6b6d585ddbb84..239dbea8fce96 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/local_storage.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/local_storage.cy.ts @@ -5,40 +5,40 @@ * 2.0. */ -import { cleanKibana, reload } from '../../../tasks/common'; +import { reload } from '../../../tasks/common'; import { login, visit } from '../../../tasks/login'; import { HOSTS_URL } from '../../../urls/navigation'; import { openEvents } from '../../../tasks/hosts/main'; -import { DATAGRID_HEADERS } from '../../../screens/timeline'; +import { DATAGRID_HEADERS, DATAGRID_HEADER } from '../../../screens/timeline'; import { waitsForEventsToBeLoaded } from '../../../tasks/hosts/events'; import { removeColumn } from '../../../tasks/timeline'; -// TODO: Fix bug in persisting the columns of timeline -describe.skip('persistent timeline', () => { +describe('persistent timeline', () => { before(() => { - cleanKibana(); login(); visit(HOSTS_URL); openEvents(); waitsForEventsToBeLoaded(); + + /* Stores in 'expectedNumberOfTimelineColumns' alias the number of columns we are going to have + after the delition of the column */ cy.get(DATAGRID_HEADERS).then((header) => cy.wrap(header.length - 1).as('expectedNumberOfTimelineColumns') ); }); it('persist the deletion of a column', function () { - const MESSAGE_COLUMN = 'message'; - const MESSAGE_COLUMN_POSITION = 2; - - cy.get(DATAGRID_HEADERS).eq(MESSAGE_COLUMN_POSITION).should('have.text', MESSAGE_COLUMN); - removeColumn(MESSAGE_COLUMN); - - cy.get(DATAGRID_HEADERS).should('have.length', this.expectedNumberOfTimelineColumns); + /* For testing purposes we are going to use the message column */ + const COLUMN = 'message'; + cy.get(DATAGRID_HEADER(COLUMN)).should('exist'); + removeColumn(COLUMN); reload(); waitsForEventsToBeLoaded(); + /* After the deletion of the message column and the reload of the page, we make sure + we have the expected number of columns and that the message column is not displayed */ cy.get(DATAGRID_HEADERS).should('have.length', this.expectedNumberOfTimelineColumns); - cy.get(DATAGRID_HEADERS).each(($el) => expect($el.text()).not.equal(MESSAGE_COLUMN)); + cy.get(DATAGRID_HEADER(COLUMN)).should('not.exist'); }); }); diff --git a/x-pack/plugins/security_solution/cypress/screens/timeline.ts b/x-pack/plugins/security_solution/cypress/screens/timeline.ts index be28b3438b26a..d46b0d04f3355 100644 --- a/x-pack/plugins/security_solution/cypress/screens/timeline.ts +++ b/x-pack/plugins/security_solution/cypress/screens/timeline.ts @@ -39,8 +39,11 @@ export const CREATE_NEW_TIMELINE_TEMPLATE = '[data-test-subj="template-timeline- export const DATA_PROVIDERS = '.field-value'; -export const DATAGRID_HEADERS = - '[data-test-subj="events-viewer-panel"] [data-test-subj^="dataGridHeaderCell-"]'; +export const DATAGRID_HEADERS = '[data-test-subj^="dataGridHeaderCell-"]'; + +export const DATAGRID_HEADER = (header: string) => { + return `[data-test-subj="dataGridHeaderCell-${header}"]`; +}; export const DATE_PICKER_END = '[data-test-subj="superDatePickerendDatePopoverButton"]'; From 62c9a1f6cb7b0f29822eeda22bdb3497a5b44d86 Mon Sep 17 00:00:00 2001 From: Coen Warmer Date: Wed, 12 Jul 2023 16:12:12 +0200 Subject: [PATCH 71/97] Add SLO Edit Form locator (#161753) --- x-pack/plugins/observability/common/index.ts | 1 + x-pack/plugins/observability/public/index.ts | 3 ++ .../public/locators/slo_edit.test.ts | 26 +++++++++++++ .../observability/public/locators/slo_edit.ts | 37 +++++++++++++++++++ x-pack/plugins/observability/public/plugin.ts | 4 ++ 5 files changed, 71 insertions(+) create mode 100644 x-pack/plugins/observability/public/locators/slo_edit.test.ts create mode 100644 x-pack/plugins/observability/public/locators/slo_edit.ts diff --git a/x-pack/plugins/observability/common/index.ts b/x-pack/plugins/observability/common/index.ts index 50d55f071ac96..1d4bf57abf285 100644 --- a/x-pack/plugins/observability/common/index.ts +++ b/x-pack/plugins/observability/common/index.ts @@ -65,6 +65,7 @@ export const alertsLocatorID = 'ALERTS_LOCATOR'; export const ruleDetailsLocatorID = 'RULE_DETAILS_LOCATOR'; export const rulesLocatorID = 'RULES_LOCATOR'; export const sloDetailsLocatorID = 'SLO_DETAILS_LOCATOR'; +export const sloEditLocatorID = 'SLO_EDIT_LOCATOR'; export type { AlertsLocatorParams } from './locators/alerts'; diff --git a/x-pack/plugins/observability/public/index.ts b/x-pack/plugins/observability/public/index.ts index 303257e7ca617..50b67fc5d0bb0 100644 --- a/x-pack/plugins/observability/public/index.ts +++ b/x-pack/plugins/observability/public/index.ts @@ -46,9 +46,12 @@ export { ruleDetailsLocatorID, rulesLocatorID, sloDetailsLocatorID, + sloEditLocatorID, uptimeOverviewLocatorID, } from '../common'; +export type { SloEditLocatorParams } from './locators/slo_edit'; + export type { UXMetrics } from './pages/overview/components/sections/ux/core_web_vitals/core_vitals'; export { getCoreVitalsComponent } from './pages/overview/components/sections/ux/core_web_vitals/get_core_web_vitals_lazy'; diff --git a/x-pack/plugins/observability/public/locators/slo_edit.test.ts b/x-pack/plugins/observability/public/locators/slo_edit.test.ts new file mode 100644 index 0000000000000..17039b72dd44a --- /dev/null +++ b/x-pack/plugins/observability/public/locators/slo_edit.test.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { buildSlo } from '../data/slo/slo'; +import { SloEditLocatorDefinition } from './slo_edit'; + +describe('SloEditLocator', () => { + const locator = new SloEditLocatorDefinition(); + + it('should return correct url when empty params are provided', async () => { + const location = await locator.getLocation({}); + expect(location.app).toEqual('observability'); + expect(location.path).toEqual('/slos/create?_a=()'); + }); + + it('should return correct url when slo is provided', async () => { + const location = await locator.getLocation(buildSlo({ id: 'foo' })); + expect(location.path).toEqual( + "/slos/edit/foo?_a=(budgetingMethod:occurrences,createdAt:'2022-12-29T10:11:12.000Z',description:'some%20description%20useful',enabled:!t,id:foo,indicator:(params:(filter:'baz:%20foo%20and%20bar%20%3E%202',good:'http_status:%202xx',index:some-index,timestampField:custom_timestamp,total:'a%20query'),type:sli.kql.custom),name:'super%20important%20level%20service',objective:(target:0.98),revision:1,settings:(frequency:'1m',syncDelay:'1m'),summary:(errorBudget:(consumed:0.064,initial:0.02,isEstimated:!f,remaining:0.936),sliValue:0.99872,status:HEALTHY),tags:!(k8s,production,critical),timeWindow:(duration:'30d',type:rolling),updatedAt:'2022-12-29T10:11:12.000Z')" + ); + }); +}); diff --git a/x-pack/plugins/observability/public/locators/slo_edit.ts b/x-pack/plugins/observability/public/locators/slo_edit.ts new file mode 100644 index 0000000000000..bac7354d34190 --- /dev/null +++ b/x-pack/plugins/observability/public/locators/slo_edit.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public'; +import type { RecursivePartial } from '@elastic/charts'; +import type { SerializableRecord } from '@kbn/utility-types'; +import type { LocatorDefinition } from '@kbn/share-plugin/public'; +import type { CreateSLOForm } from '../pages/slo_edit/types'; +import { sloEditLocatorID } from '../../common'; +import { SLO_CREATE_PATH, SLOS_PATH } from '../routes/paths'; + +export type SloEditParams = RecursivePartial; + +export interface SloEditLocatorParams extends SloEditParams, SerializableRecord {} + +export class SloEditLocatorDefinition implements LocatorDefinition { + public readonly id = sloEditLocatorID; + + public readonly getLocation = async (slo: SloEditLocatorParams) => { + return { + app: 'observability', + path: setStateToKbnUrl( + '_a', + { + ...slo, + }, + { useHash: false, storeInHashQuery: false }, + slo.id ? `${SLOS_PATH}/edit/${encodeURI(String(slo.id))}` : SLO_CREATE_PATH + ), + state: {}, + }; + }; +} diff --git a/x-pack/plugins/observability/public/plugin.ts b/x-pack/plugins/observability/public/plugin.ts index 78bb07a0ee662..24c1d2a84ca47 100644 --- a/x-pack/plugins/observability/public/plugin.ts +++ b/x-pack/plugins/observability/public/plugin.ts @@ -54,6 +54,7 @@ import { ExploratoryViewPublicStart } from '@kbn/exploratory-view-plugin/public' import { RulesLocatorDefinition } from './locators/rules'; import { RuleDetailsLocatorDefinition } from './locators/rule_details'; import { SloDetailsLocatorDefinition } from './locators/slo_details'; +import { SloEditLocatorDefinition } from './locators/slo_edit'; import { observabilityAppId, observabilityFeatureId } from '../common'; import { registerDataHandler } from './context/has_data_context/data_handler'; import { @@ -223,6 +224,8 @@ export class Plugin new SloDetailsLocatorDefinition() ); + const sloEditLocator = pluginsSetup.share.url.locators.create(new SloEditLocatorDefinition()); + const mount = async (params: AppMountParameters) => { // Load application bundle const { renderApp } = await import('./application'); @@ -349,6 +352,7 @@ export class Plugin rulesLocator, ruleDetailsLocator, sloDetailsLocator, + sloEditLocator, getCoPilotService: () => this.coPilotService!, }; } From c4790da182427f6793ef8082d9f9a4285385e821 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Wed, 12 Jul 2023 09:31:44 -0500 Subject: [PATCH 72/97] fix: return decoded urls on CloudStart as well as CloudSetup (#161711) ## Summary #159442 updated the decoding of the cloud id and added `elasticsearchUrl` & `kibanaUrl` to the `CloudStart` type, but it only set them on the `CloudSetup` result. This change will also add them to the `CloudStart` so they are available to code that is trying to read the values from `CloudStart` , mainly [serverless_search](https://github.com/elastic/kibana/blob/main/x-pack/plugins/serverless_search/public/application/components/overview.tsx#L49-L51) is what I'm concerned with. --- x-pack/plugins/cloud/public/plugin.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/x-pack/plugins/cloud/public/plugin.tsx b/x-pack/plugins/cloud/public/plugin.tsx index 78bd6a8a9ef9a..b17614bb3c41e 100644 --- a/x-pack/plugins/cloud/public/plugin.tsx +++ b/x-pack/plugins/cloud/public/plugin.tsx @@ -103,6 +103,11 @@ export class CloudPlugin implements Plugin { const { deploymentUrl, profileUrl, billingUrl, organizationUrl } = this.getCloudUrls(); + let decodedId: DecodedCloudId | undefined; + if (this.config.id) { + decodedId = decodeCloudId(this.config.id, this.logger); + } + return { CloudContextProvider, isCloudEnabled: this.isCloudEnabled, @@ -111,6 +116,8 @@ export class CloudPlugin implements Plugin { deploymentUrl, profileUrl, organizationUrl, + elasticsearchUrl: decodedId?.elasticsearchUrl, + kibanaUrl: decodedId?.kibanaUrl, }; } From d166193ac04a8a3db48f252bc90ca36928427507 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 12 Jul 2023 16:32:57 +0200 Subject: [PATCH 73/97] [Synthetics] Optimise get last 50 checks query (#161742) --- .../monitor_management/monitor_types.ts | 1 + .../overview/actions_popover.test.tsx | 1 + .../overview/overview/overview_grid.test.tsx | 2 + .../overview/overview/overview_grid_item.tsx | 1 + .../hooks/use_last_50_duration_chart.test.ts | 18 ++-- .../hooks/use_last_50_duration_chart.ts | 3 + .../hooks/use_last_x_checks.test.tsx | 29 ++++- .../synthetics/hooks/use_last_x_checks.ts | 20 +++- .../routes/monitor_cruds/get_monitor.test.ts | 101 ++++++++++++++++++ .../routes/monitor_cruds/get_monitor.ts | 5 +- .../apis/synthetics/get_monitor_overview.ts | 12 ++- 11 files changed, 180 insertions(+), 13 deletions(-) create mode 100644 x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.test.ts diff --git a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts index cd9e96081778b..979919d6614a5 100644 --- a/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -395,6 +395,7 @@ export const MonitorOverviewItemCodec = t.intersection([ isStatusAlertEnabled: t.boolean, type: t.string, tags: t.array(t.string), + schedule: t.string, }), t.partial({ projectId: t.string, diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.test.tsx index e278aa9a3f5b4..ea8edd7878a40 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.test.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/actions_popover.test.tsx @@ -31,6 +31,7 @@ describe('ActionsPopover', () => { configId: '1lkjelre', type: 'browser', tags: [], + schedule: '120', }; }); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx index ed470f6f24bce..3ea7d5e0ba5b3 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx @@ -32,6 +32,7 @@ describe('Overview Grid', () => { isStatusAlertEnabled: true, type: 'browser', tags: [], + schedule: '60', }); data.push({ id: `${i}`, @@ -45,6 +46,7 @@ describe('Overview Grid', () => { isStatusAlertEnabled: true, type: 'browser', tags: [], + schedule: '60', }); } return data; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item.tsx index 952a48d424733..3fb27e202f996 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid_item.tsx @@ -36,6 +36,7 @@ export const OverviewGridItem = ({ locationId: monitor.location?.id, monitorId: monitor.id, timestamp, + schedule: monitor.schedule, }); return ( { jest.spyOn(hooks, 'useLastXChecks').mockReturnValue({ hits: getMockHits(), loading: false }); const { result } = renderHook( - () => useLast50DurationChart({ monitorId: 'mock-id', locationId: 'loc' }), + () => useLast50DurationChart({ monitorId: 'mock-id', locationId: 'loc', schedule: '1' }), { wrapper: WrappedHelper } ); expect(result.current).toEqual({ @@ -91,7 +91,7 @@ describe('useLast50DurationChart', () => { .spyOn(hooks, 'useLastXChecks') .mockReturnValue({ hits: hitsWithAnUndefinedDuration, loading: false }); const { result } = renderHook( - () => useLast50DurationChart({ monitorId: 'mock-id', locationId: 'loc' }), + () => useLast50DurationChart({ monitorId: 'mock-id', locationId: 'loc', schedule: '10' }), { wrapper: WrappedHelper } ); @@ -153,7 +153,7 @@ describe('useLast50DurationChart', () => { const spy = jest .spyOn(hooks, 'useLastXChecks') .mockReturnValue({ hits: hitsWithAnUndefinedDuration, loading: false }); - renderHook(() => useLast50DurationChart({ monitorId, locationId }), { + renderHook(() => useLast50DurationChart({ monitorId, locationId, schedule: '120' }), { wrapper: WrappedHelper, }); @@ -163,6 +163,7 @@ describe('useLast50DurationChart', () => { locationId, fields: ['monitor.duration.us'], size: 50, + schedule: '120', }); }); @@ -171,12 +172,15 @@ describe('useLast50DurationChart', () => { jest.spyOn(hooks, 'useLastXChecks').mockReturnValue({ hits: getMockHits(), loading }); const { result } = renderHook( - () => useLast50DurationChart({ monitorId: 'mock-id', locationId: 'loc' }), + () => useLast50DurationChart({ monitorId: 'mock-id', locationId: 'loc', schedule: '3' }), { wrapper: WrappedHelper } ); - renderHook(() => useLast50DurationChart({ monitorId: 'test-id', locationId: 'loc' }), { - wrapper: WrappedHelper, - }); + renderHook( + () => useLast50DurationChart({ monitorId: 'test-id', locationId: 'loc', schedule: '5' }), + { + wrapper: WrappedHelper, + } + ); expect(result.current.loading).toEqual(loading); }); }); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts index 8cb7d524635c7..f08e025a48540 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts @@ -14,10 +14,12 @@ export function useLast50DurationChart({ monitorId, locationId, timestamp, + schedule, }: { monitorId: string; timestamp?: string; locationId: string; + schedule: string; }) { const { hits, loading } = useLastXChecks<{ 'monitor.duration.us': number[] | undefined; @@ -27,6 +29,7 @@ export function useLast50DurationChart({ fields, size: 50, timestamp, + schedule, }); const { data, median, min, max, avg } = useMemo(() => { if (loading) { diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_x_checks.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_x_checks.test.tsx index 0a6154ab76244..8c16902357273 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_x_checks.test.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_x_checks.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; import { renderHook } from '@testing-library/react-hooks'; -import { useLastXChecks } from './use_last_x_checks'; +import { getTimeRangeFilter, useLastXChecks } from './use_last_x_checks'; import { WrappedHelper } from '../utils/testing'; import * as searchHooks from './use_redux_es_search'; import { SYNTHETICS_INDEX_PATTERN } from '../../../../common/constants'; @@ -40,6 +40,7 @@ describe('useLastXChecks', () => { locationId: 'loc', size: 30, fields: ['monitor.duration.us'], + schedule: '10', }), { wrapper: WrappedHelper } ); @@ -95,6 +96,7 @@ describe('useLastXChecks', () => { locationId: 'loc', size, fields, + schedule: '120', }), { wrapper: WrappedHelper } ); @@ -118,6 +120,7 @@ describe('useLastXChecks', () => { locationId: 'loc', size: 30, fields: ['monitor.duration.us'], + schedule: '240', }), { wrapper: WrappedHelper } ); @@ -136,6 +139,7 @@ describe('useLastXChecks', () => { locationId: 'loc', size: 30, fields: ['monitor.duration.us'], + schedule: '1', }), { wrapper: WrappedHelper } ); @@ -164,6 +168,7 @@ describe('useLastXChecks', () => { locationId: 'loc', size: 30, fields: ['monitor.duration.us'], + schedule: '3', }), { wrapper: WrapperWithState } ); @@ -174,3 +179,25 @@ describe('useLastXChecks', () => { ); }); }); + +describe('getTimeRangeFilter', () => { + it.each([ + [1, 'now-1h'], + [3, 'now-3h'], + [5, 'now-5h'], + [10, 'now-9h'], + [60, 'now-50h'], + [120, 'now-100h'], + [240, 'now-200h'], + ])('returns expected filter', (val, res) => { + const filter = getTimeRangeFilter(String(val)); + expect(filter).toEqual({ + range: { + '@timestamp': { + gte: res, + lte: 'now', + }, + }, + }); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_x_checks.ts b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_x_checks.ts index 2d7cc1775e05f..d83da872ab451 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_x_checks.ts +++ b/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_last_x_checks.ts @@ -20,14 +20,30 @@ import { selectServiceLocationsState } from '../state'; import { useSyntheticsRefreshContext } from '../contexts/synthetics_refresh_context'; import { SYNTHETICS_INDEX_PATTERN, UNNAMED_LOCATION } from '../../../../common/constants'; +export const getTimeRangeFilter = (schedule: string) => { + const inMinutes = Number(schedule); + const fiftyChecksInMinutes = inMinutes * 50; + const hours = Math.ceil(fiftyChecksInMinutes / 60); + return { + range: { + '@timestamp': { + gte: `now-${hours}h`, + lte: 'now', + }, + }, + }; +}; + export function useLastXChecks({ monitorId, locationId, fields = ['*'], size = 50, timestamp, + schedule, }: { monitorId: string; + schedule: string; locationId: string; timestamp?: string; fields?: string[]; @@ -45,6 +61,7 @@ export function useLastXChecks({ filter: [ SUMMARY_FILTER, EXCLUDE_RUN_ONCE_FILTER, + getTimeRangeFilter(schedule), { term: { 'monitor.id': monitorId, @@ -58,13 +75,14 @@ export function useLastXChecks({ }), }, }, + _source: false, sort: [{ '@timestamp': 'desc' }], fields, }, }); const { data } = useReduxEsSearch(params, [lastRefresh], { - name: `zGetLastXMonitorRunsByLocation/${monitorId}/${locationId}`, + name: `zGetLastXChecks/${monitorId}/${locationId}`, isRequestReady: locationsLoaded && Boolean(timestamp), // don't run query until locations are loaded }); diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.test.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.test.ts new file mode 100644 index 0000000000000..f439322632372 --- /dev/null +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.test.ts @@ -0,0 +1,101 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getOverviewConfigsPerLocation } from './get_monitor'; +import { EncryptedSyntheticsMonitor } from '../../../common/runtime_types'; + +describe('getOverviewConfigsPerLocation', () => { + it('returns a map of locations to monitor configs', () => { + const result = getOverviewConfigsPerLocation(attributes as EncryptedSyntheticsMonitor); + expect(result).toEqual([ + { + configId: 'cfb51782-7152-43db-9986-02b34d5e5a8c', + id: 'cfb51782-7152-43db-9986-02b34d5e5a8c', + isEnabled: true, + isStatusAlertEnabled: true, + location: { id: 'us_central', isServiceManaged: true, label: 'North America - US Central' }, + name: 'https://simonhearne.com/', + projectId: undefined, + schedule: '3', + tags: [], + type: 'http', + }, + { + configId: 'cfb51782-7152-43db-9986-02b34d5e5a8c', + id: 'cfb51782-7152-43db-9986-02b34d5e5a8c', + isEnabled: true, + isStatusAlertEnabled: true, + location: { id: 'us_central_qa', isServiceManaged: true, label: 'US Central QA' }, + name: 'https://simonhearne.com/', + projectId: undefined, + schedule: '3', + tags: [], + type: 'http', + }, + ]); + }); + it('returns a map of locations to monitor configs with queried locations', () => { + const result = getOverviewConfigsPerLocation( + attributes as EncryptedSyntheticsMonitor, + 'us_central' + ); + expect(result).toEqual([ + { + configId: 'cfb51782-7152-43db-9986-02b34d5e5a8c', + id: 'cfb51782-7152-43db-9986-02b34d5e5a8c', + isEnabled: true, + isStatusAlertEnabled: true, + location: { id: 'us_central', isServiceManaged: true, label: 'North America - US Central' }, + name: 'https://simonhearne.com/', + projectId: undefined, + schedule: '3', + tags: [], + type: 'http', + }, + ]); + }); +}); + +const attributes = { + type: 'http', + form_monitor_type: 'http', + enabled: true, + alert: { status: { enabled: true }, tls: { enabled: true } }, + schedule: { number: '3', unit: 'm' }, + 'service.name': '', + config_id: 'cfb51782-7152-43db-9986-02b34d5e5a8c', + tags: [], + timeout: '16', + name: 'https://simonhearne.com/', + locations: [ + { isServiceManaged: true, id: 'us_central', label: 'North America - US Central' }, + { isServiceManaged: true, id: 'us_central_qa', label: 'US Central QA' }, + ], + namespace: 'default', + origin: 'ui', + journey_id: '', + hash: '', + id: 'cfb51782-7152-43db-9986-02b34d5e5a8c', + __ui: { is_tls_enabled: false }, + urls: 'https://simonhearne.com/', + max_redirects: '0', + 'url.port': null, + proxy_url: '', + 'response.include_body': 'on_error', + 'response.include_headers': true, + 'check.response.status': [], + 'check.request.method': 'GET', + mode: 'any', + 'response.include_body_max_bytes': '1024', + ipv4: true, + ipv6: true, + 'ssl.certificate_authorities': '', + 'ssl.certificate': '', + 'ssl.verification_mode': 'full', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], + revision: 2, +}; diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts index 24e2d895f18e0..e9063d2eb4879 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts @@ -123,9 +123,9 @@ export const getSyntheticsMonitorOverviewRoute: SyntheticsRestApiRouteFactory = }, }); -function getOverviewConfigsPerLocation( +export function getOverviewConfigsPerLocation( attributes: EncryptedSyntheticsMonitor, - queriedLocations: string | string[] | undefined + queriedLocations?: string | string[] ) { const id = attributes[ConfigKey.MONITOR_QUERY_ID]; const configId = attributes[ConfigKey.CONFIG_ID]; @@ -149,6 +149,7 @@ function getOverviewConfigsPerLocation( configId, location, name: attributes[ConfigKey.NAME], + schedule: attributes[ConfigKey.SCHEDULE].number, tags: attributes[ConfigKey.TAGS], isEnabled: attributes[ConfigKey.ENABLED], type: attributes[ConfigKey.MONITOR_TYPE], diff --git a/x-pack/test/api_integration/apis/synthetics/get_monitor_overview.ts b/x-pack/test/api_integration/apis/synthetics/get_monitor_overview.ts index 3225749712ead..184e6883484e0 100644 --- a/x-pack/test/api_integration/apis/synthetics/get_monitor_overview.ts +++ b/x-pack/test/api_integration/apis/synthetics/get_monitor_overview.ts @@ -10,6 +10,7 @@ import { ConfigKey, SyntheticsMonitor, MonitorFields, + MonitorOverviewItem, } from '@kbn/synthetics-plugin/common/runtime_types'; import { SYNTHETICS_API_URLS } from '@kbn/synthetics-plugin/common/constants'; import expect from '@kbn/expect'; @@ -175,7 +176,8 @@ export default function ({ getService }: FtrProviderContext) { const apiResponse = await supertest .get(`/s/${SPACE_ID}${SYNTHETICS_API_URLS.SYNTHETICS_OVERVIEW}`) .query({ sortField: 'status' }); - expect(apiResponse.body.monitors).eql([ + + const expected: MonitorOverviewItem[] = [ { id: savedMonitors[0].attributes[ConfigKey.MONITOR_QUERY_ID], configId: savedMonitors[0].id, @@ -194,6 +196,7 @@ export default function ({ getService }: FtrProviderContext) { isStatusAlertEnabled: true, tags: ['tag1', 'tag2'], type: 'http', + schedule: '5', }, { id: savedMonitors[0].attributes[ConfigKey.MONITOR_QUERY_ID], @@ -213,6 +216,7 @@ export default function ({ getService }: FtrProviderContext) { isStatusAlertEnabled: true, tags: ['tag1', 'tag2'], type: 'http', + schedule: '5', }, { id: savedMonitors[1].attributes[ConfigKey.MONITOR_QUERY_ID], @@ -232,6 +236,7 @@ export default function ({ getService }: FtrProviderContext) { isStatusAlertEnabled: true, tags: ['tag1', 'tag2'], type: 'http', + schedule: '5', }, { id: savedMonitors[1].attributes[ConfigKey.MONITOR_QUERY_ID], @@ -251,8 +256,11 @@ export default function ({ getService }: FtrProviderContext) { isStatusAlertEnabled: true, tags: ['tag1', 'tag2'], type: 'http', + schedule: '5', }, - ]); + ]; + + expect(apiResponse.body.monitors).eql(expected); expect(savedMonitors[1].attributes[ConfigKey.MONITOR_QUERY_ID]).eql(customHeartbeatId); } finally { await Promise.all( From 3a434bfe852179335155a8fdbbcb43904743b838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Wed, 12 Jul 2023 15:46:41 +0100 Subject: [PATCH 74/97] [ColorScheme] Update from avatar menu (#161214) --- packages/kbn-optimizer/limits.yml | 2 +- .../maybe_add_cloud_links.test.ts | 156 ++++++++++- .../maybe_add_cloud_links.ts | 6 +- .../theme_darkmode_hook.ts | 77 +++++ .../theme_darkmode_toggle.test.tsx | 57 ++++ .../theme_darkmode_toggle.tsx | 80 ++++++ ...user_menu_links.ts => user_menu_links.tsx} | 23 +- .../cloud_links/public/plugin.tsx | 8 +- .../cloud_links/tsconfig.json | 1 + .../security/common/model/user_profile.ts | 4 +- .../public/account_management/index.ts | 1 + .../account_management/user_profile/index.ts | 2 + .../use_update_user_profile.test.tsx | 138 +++++++++ .../user_profile/use_update_user_profile.tsx | 150 ++++++++++ .../user_profile/user_profile.tsx | 85 ++---- .../user_profile_api_client.test.ts | 1 + .../user_profile/user_profile_api_client.ts | 33 ++- x-pack/plugins/security/public/index.ts | 1 + x-pack/plugins/security/public/mocks.ts | 13 +- .../nav_control_component.test.tsx | 263 ++++++++++-------- .../nav_control/nav_control_component.tsx | 48 +++- .../plugins/security/public/plugin.test.tsx | 15 + x-pack/plugins/security/public/plugin.tsx | 24 +- .../server/lib/flatten_object.test.ts | 43 +++ .../security/server/lib/flatten_object.ts | 35 +++ x-pack/plugins/security/server/lib/index.ts | 1 + .../server/routes/user_profile/update.test.ts | 29 ++ .../server/routes/user_profile/update.ts | 25 +- .../functional_cloud/tests/cloud_links.ts | 6 + 29 files changed, 1126 insertions(+), 201 deletions(-) create mode 100644 x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_hook.ts create mode 100644 x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.test.tsx create mode 100644 x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx rename x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/{user_menu_links.ts => user_menu_links.tsx} (67%) create mode 100644 x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.test.tsx create mode 100644 x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx create mode 100644 x-pack/plugins/security/server/lib/flatten_object.test.ts create mode 100644 x-pack/plugins/security/server/lib/flatten_object.ts diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 3a1a8387feaa7..ac968b0d84dcc 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -116,7 +116,7 @@ pageLoadAssetSize: screenshotMode: 17856 screenshotting: 22870 searchprofiler: 67080 - security: 65433 + security: 81771 securitySolution: 66738 securitySolutionEss: 16573 securitySolutionServerless: 40000 diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts index 16d29325502e1..f2e14d1a08526 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts @@ -19,6 +19,7 @@ describe('maybeAddCloudLinks', () => { chrome: coreMock.createStart().chrome, cloud: { ...cloudMock.createStart(), isCloudEnabled: false }, docLinks: coreMock.createStart().docLinks, + uiSettingsClient: coreMock.createStart().uiSettings, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); @@ -30,12 +31,13 @@ describe('maybeAddCloudLinks', () => { security.authc.getCurrentUser.mockResolvedValue( securityMock.createMockAuthenticatedUser({ elastic_cloud_user: true }) ); - const { chrome, docLinks } = coreMock.createStart(); + const { chrome, docLinks, uiSettings } = coreMock.createStart(); maybeAddCloudLinks({ security, chrome, cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, docLinks, + uiSettingsClient: uiSettings, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); @@ -73,6 +75,79 @@ describe('maybeAddCloudLinks', () => { "label": "Organization", "order": 300, }, + Object { + "content": , + "href": "", + "iconType": "", + "label": "", + "order": 400, + }, ], ] `); @@ -101,12 +176,13 @@ describe('maybeAddCloudLinks', () => { it('when cloud enabled and it fails to fetch the user, it sets the links', async () => { const security = securityMock.createStart(); security.authc.getCurrentUser.mockRejectedValue(new Error('Something went terribly wrong')); - const { chrome, docLinks } = coreMock.createStart(); + const { chrome, docLinks, uiSettings } = coreMock.createStart(); maybeAddCloudLinks({ security, chrome, cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, docLinks, + uiSettingsClient: uiSettings, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); @@ -144,6 +220,79 @@ describe('maybeAddCloudLinks', () => { "label": "Organization", "order": 300, }, + Object { + "content": , + "href": "", + "iconType": "", + "label": "", + "order": 400, + }, ], ] `); @@ -173,12 +322,13 @@ describe('maybeAddCloudLinks', () => { security.authc.getCurrentUser.mockResolvedValue( securityMock.createMockAuthenticatedUser({ elastic_cloud_user: false }) ); - const { chrome, docLinks } = coreMock.createStart(); + const { chrome, docLinks, uiSettings } = coreMock.createStart(); maybeAddCloudLinks({ security, chrome, cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, docLinks, + uiSettingsClient: uiSettings, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts index 3d7aa271ed866..1becd2cdf7254 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import type { CloudStart } from '@kbn/cloud-plugin/public'; import type { ChromeStart } from '@kbn/core/public'; import type { SecurityPluginStart } from '@kbn/security-plugin/public'; - +import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; import type { DocLinksStart } from '@kbn/core-doc-links-browser'; import { createUserMenuLinks } from './user_menu_links'; import { createHelpMenuLinks } from './help_menu_links'; @@ -21,6 +21,7 @@ export interface MaybeAddCloudLinksDeps { chrome: ChromeStart; cloud: CloudStart; docLinks: DocLinksStart; + uiSettingsClient: IUiSettingsClient; } export function maybeAddCloudLinks({ @@ -28,6 +29,7 @@ export function maybeAddCloudLinks({ chrome, cloud, docLinks, + uiSettingsClient, }: MaybeAddCloudLinksDeps): void { const userObservable = defer(() => security.authc.getCurrentUser()).pipe( // Check if user is a cloud user. @@ -45,7 +47,7 @@ export function maybeAddCloudLinks({ href: cloud.deploymentUrl, }); } - const userMenuLinks = createUserMenuLinks(cloud); + const userMenuLinks = createUserMenuLinks({ cloud, security, uiSettingsClient }); security.navControlService.addUserMenuLinks(userMenuLinks); }) ); diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_hook.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_hook.ts new file mode 100644 index 0000000000000..75d6ae4d1d329 --- /dev/null +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_hook.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback, useEffect, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import type { SecurityPluginStart } from '@kbn/security-plugin/public'; +import { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; + +interface Deps { + uiSettingsClient: IUiSettingsClient; + security: SecurityPluginStart; +} + +export const useThemeDarkmodeToggle = ({ uiSettingsClient, security }: Deps) => { + const [isDarkModeOn, setIsDarkModeOn] = useState(false); + // If a value is set in kibana.yml (uiSettings.overrides.theme:darkMode) + // we don't allow the user to change the theme color. + const valueSetInKibanaConfig = uiSettingsClient.isOverridden('theme:darkMode'); + + const { userProfileData, isLoading, update } = security.hooks.useUpdateUserProfile({ + notificationSuccess: { + title: i18n.translate('xpack.cloudLinks.userMenuLinks.darkMode.successNotificationTitle', { + defaultMessage: 'Color theme updated', + }), + pageReloadText: i18n.translate( + 'xpack.cloudLinks.userMenuLinks.darkMode.successNotificationText', + { + defaultMessage: 'Reload the page to see the changes', + } + ), + }, + pageReloadChecker: (prev, next) => { + return prev?.userSettings?.darkMode !== next.userSettings?.darkMode; + }, + }); + + const { userSettings: { darkMode: colorScheme } = { darkMode: undefined } } = + userProfileData ?? {}; + + const toggle = useCallback( + (on: boolean) => { + if (isLoading) { + return; + } + update({ + userSettings: { + darkMode: on ? 'dark' : 'light', + }, + }); + }, + [isLoading, update] + ); + + useEffect(() => { + let updatedValue = false; + + if (typeof colorScheme !== 'string') { + // User profile does not have yet any preference -> default to space dark mode value + updatedValue = uiSettingsClient.get('theme:darkMode') ?? false; + } else { + updatedValue = colorScheme === 'dark'; + } + + setIsDarkModeOn(updatedValue); + }, [colorScheme, uiSettingsClient]); + + return { + isVisible: valueSetInKibanaConfig ? false : Boolean(userProfileData), + toggle, + isDarkModeOn, + colorScheme, + }; +}; diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.test.tsx b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.test.tsx new file mode 100644 index 0000000000000..2bebdad488498 --- /dev/null +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.test.tsx @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render, fireEvent } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { coreMock } from '@kbn/core/public/mocks'; +import { securityMock } from '@kbn/security-plugin/public/mocks'; + +import { ThemDarkModeToggle } from './theme_darkmode_toggle'; + +describe('ThemDarkModeToggle', () => { + const mockUseUpdateUserProfile = jest.fn(); + const mockGetSpaceDarkModeValue = jest.fn(); + + it('renders correctly and toggles dark mode', () => { + const security = { + ...securityMock.createStart(), + hooks: { useUpdateUserProfile: mockUseUpdateUserProfile }, + }; + const { uiSettings } = coreMock.createStart(); + + const mockUpdate = jest.fn(); + mockUseUpdateUserProfile.mockReturnValue({ + userProfileData: { userSettings: { darkMode: 'light' } }, + isLoading: false, + update: mockUpdate, + }); + + mockGetSpaceDarkModeValue.mockReturnValue(false); + + const { getByTestId, rerender } = render( + + ); + + const toggleSwitch = getByTestId('darkModeToggleSwitch'); + fireEvent.click(toggleSwitch); + expect(mockUpdate).toHaveBeenCalledWith({ userSettings: { darkMode: 'dark' } }); + + // Now we want to simulate toggling back to light + mockUseUpdateUserProfile.mockReturnValue({ + userProfileData: { userSettings: { darkMode: 'dark' } }, + isLoading: false, + update: mockUpdate, + }); + + // Rerender the component to apply the new props + rerender(); + + fireEvent.click(toggleSwitch); + expect(mockUpdate).toHaveBeenLastCalledWith({ userSettings: { darkMode: 'light' } }); + }); +}); diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx new file mode 100644 index 0000000000000..3f85c2ed63a76 --- /dev/null +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { + EuiContextMenuItem, + EuiFlexGroup, + EuiFlexItem, + EuiSwitch, + useEuiTheme, + useGeneratedHtmlId, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import type { SecurityPluginStart } from '@kbn/security-plugin/public'; +import { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; +import { useThemeDarkmodeToggle } from './theme_darkmode_hook'; + +interface Props { + uiSettingsClient: IUiSettingsClient; + security: SecurityPluginStart; +} + +export const ThemDarkModeToggle = ({ security, uiSettingsClient }: Props) => { + const toggleTextSwitchId = useGeneratedHtmlId({ prefix: 'toggleTextSwitch' }); + const { euiTheme } = useEuiTheme(); + + const { isVisible, toggle, isDarkModeOn, colorScheme } = useThemeDarkmodeToggle({ + security, + uiSettingsClient, + }); + + if (!isVisible) { + return null; + } + + return ( + + + { + const on = colorScheme === 'light' ? true : false; + toggle(on); + }} + data-test-subj="darkModeToggle" + > + {i18n.translate('xpack.cloudLinks.userMenuLinks.darkModeToggle', { + defaultMessage: 'Dark mode', + })} + + + + { + toggle(e.target.checked); + }} + aria-describedby={toggleTextSwitchId} + data-test-subj="darkModeToggleSwitch" + compressed + /> + + + ); +}; diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.tsx similarity index 67% rename from x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.ts rename to x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.tsx index b6996a2f8f5a2..1eae5d6ed0c58 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.tsx @@ -5,11 +5,22 @@ * 2.0. */ +import React from 'react'; import { i18n } from '@kbn/i18n'; import type { CloudStart } from '@kbn/cloud-plugin/public'; -import type { UserMenuLink } from '@kbn/security-plugin/public'; +import type { SecurityPluginStart, UserMenuLink } from '@kbn/security-plugin/public'; +import { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; +import { ThemDarkModeToggle } from './theme_darkmode_toggle'; -export const createUserMenuLinks = (cloud: CloudStart): UserMenuLink[] => { +export const createUserMenuLinks = ({ + cloud, + security, + uiSettingsClient, +}: { + cloud: CloudStart; + security: SecurityPluginStart; + uiSettingsClient: IUiSettingsClient; +}): UserMenuLink[] => { const { profileUrl, billingUrl, organizationUrl } = cloud; const userMenuLinks = [] as UserMenuLink[]; @@ -48,5 +59,13 @@ export const createUserMenuLinks = (cloud: CloudStart): UserMenuLink[] => { }); } + userMenuLinks.push({ + content: , + order: 400, + label: '', + iconType: '', + href: '', + }); + return userMenuLinks; }; diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx index 1eb490ba0cd3a..7ee3f0969251d 100755 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx @@ -43,7 +43,13 @@ export class CloudLinksPlugin }); } if (security) { - maybeAddCloudLinks({ security, chrome: core.chrome, cloud, docLinks: core.docLinks }); + maybeAddCloudLinks({ + security, + chrome: core.chrome, + cloud, + docLinks: core.docLinks, + uiSettingsClient: core.uiSettings, + }); } } } diff --git a/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json b/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json index a57da9edc3199..0dfa7ce42858d 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json +++ b/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json @@ -19,6 +19,7 @@ "@kbn/guided-onboarding-plugin", "@kbn/core-chrome-browser", "@kbn/core-doc-links-browser", + "@kbn/core-ui-settings-browser", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/security/common/model/user_profile.ts b/x-pack/plugins/security/common/model/user_profile.ts index a39f56a4bff96..c4dd6addd51fc 100644 --- a/x-pack/plugins/security/common/model/user_profile.ts +++ b/x-pack/plugins/security/common/model/user_profile.ts @@ -90,11 +90,13 @@ export interface UserProfileAvatarData { imageUrl?: string | null; } +export type DarkModeValue = '' | 'dark' | 'light'; + /** * User settings stored in the data object of the User Profile */ export interface UserSettingsData { - darkMode?: string; + darkMode?: DarkModeValue; } /** diff --git a/x-pack/plugins/security/public/account_management/index.ts b/x-pack/plugins/security/public/account_management/index.ts index e1a4957aa71e7..eca7287537318 100644 --- a/x-pack/plugins/security/public/account_management/index.ts +++ b/x-pack/plugins/security/public/account_management/index.ts @@ -11,4 +11,5 @@ export type { UserProfileBulkGetParams, UserProfileGetCurrentParams, UserProfileSuggestParams, + UpdateUserProfileHook, } from './user_profile'; diff --git a/x-pack/plugins/security/public/account_management/user_profile/index.ts b/x-pack/plugins/security/public/account_management/user_profile/index.ts index ed34d7d4a4339..93a1c7d04d315 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/index.ts +++ b/x-pack/plugins/security/public/account_management/user_profile/index.ts @@ -13,3 +13,5 @@ export type { UserProfileBulkGetParams, UserProfileSuggestParams, } from './user_profile_api_client'; + +export type { UpdateUserProfileHook } from './use_update_user_profile'; diff --git a/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.test.tsx b/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.test.tsx new file mode 100644 index 0000000000000..6690e9b6cf946 --- /dev/null +++ b/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.test.tsx @@ -0,0 +1,138 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { act, renderHook } from '@testing-library/react-hooks'; +import { BehaviorSubject, first, lastValueFrom } from 'rxjs'; + +import { coreMock } from '@kbn/core/public/mocks'; + +import { getUseUpdateUserProfile } from './use_update_user_profile'; +import { UserProfileAPIClient } from './user_profile_api_client'; + +const { notifications, http } = coreMock.createStart(); +const userProfileApiClient = new UserProfileAPIClient(http); +const useUpdateUserProfile = getUseUpdateUserProfile({ + apiClient: userProfileApiClient, + notifications, +}); + +describe('useUpdateUserProfile', () => { + let spy: jest.SpyInstance; + + beforeEach(() => { + spy = jest.spyOn(userProfileApiClient, 'update'); + http.get.mockReset(); + http.post.mockReset().mockResolvedValue(undefined); + notifications.toasts.addSuccess.mockReset(); + }); + + afterEach(() => { + spy.mockRestore(); + }); + + test('should call the apiClient with the updated user profile data', async () => { + const { result } = renderHook(() => useUpdateUserProfile()); + const { update } = result.current; + + await act(async () => { + update({ userSettings: { darkMode: 'dark' } }); + }); + + expect(spy).toHaveBeenCalledWith({ userSettings: { darkMode: 'dark' } }); + }); + + test('should update the isLoading state while updating', async () => { + const { result, waitForNextUpdate } = renderHook(() => useUpdateUserProfile()); + const { update } = result.current; + const httpPostDone = new BehaviorSubject(false); + + http.post.mockImplementationOnce(async () => { + await lastValueFrom(httpPostDone.pipe(first((v) => v === true))); + }); + + expect(result.current.isLoading).toBeFalsy(); + + await act(async () => { + update({ userSettings: { darkMode: 'dark' } }); + }); + + expect(result.current.isLoading).toBeTruthy(); + + httpPostDone.next(true); // Resolve the http.post promise + await waitForNextUpdate(); + + expect(result.current.isLoading).toBeFalsy(); + }); + + test('should show a success notification by default', async () => { + const { result } = renderHook(() => useUpdateUserProfile()); + const { update } = result.current; + + await act(async () => { + await update({ userSettings: { darkMode: 'dark' } }); + }); + + expect(notifications.toasts.addSuccess).toHaveBeenCalledWith( + { + title: 'Profile updated', + }, + {} // toast options + ); + }); + + test('should show a notification with reload page button when refresh is required', async () => { + const pageReloadChecker = () => { + return true; + }; + + const { result } = renderHook(() => + useUpdateUserProfile({ + pageReloadChecker, + }) + ); + const { update } = result.current; + + await act(async () => { + await update({ userSettings: { darkMode: 'dark' } }); + }); + + expect(notifications.toasts.addSuccess).toHaveBeenCalledWith( + { + title: 'Profile updated', + text: expect.any(Function), // React node + }, + { + toastLifeTimeMs: 300000, // toast options + } + ); + }); + + test('should pass the previous and next user profile data to the pageReloadChecker', async () => { + const pageReloadChecker = jest.fn(); + + const initialValue = { foo: 'bar' }; + http.get.mockReset().mockResolvedValue({ data: initialValue }); + const userProfileApiClient2 = new UserProfileAPIClient(http); + await userProfileApiClient2.getCurrent(); // Sets the initial value of the userProfile$ Observable + + const { result } = renderHook(() => + getUseUpdateUserProfile({ + apiClient: userProfileApiClient2, + notifications, + })({ + pageReloadChecker, + }) + ); + const { update } = result.current; + + const nextValue = { userSettings: { darkMode: 'light' as const } }; + await act(async () => { + await update(nextValue); + }); + + expect(pageReloadChecker).toHaveBeenCalledWith(initialValue, nextValue); + }); +}); diff --git a/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx b/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx new file mode 100644 index 0000000000000..2dafa61496fe8 --- /dev/null +++ b/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import React, { useCallback, useRef, useState } from 'react'; +import useObservable from 'react-use/lib/useObservable'; + +import type { NotificationsStart, ToastInput, ToastOptions } from '@kbn/core/public'; +import { i18n } from '@kbn/i18n'; +import { toMountPoint } from '@kbn/kibana-react-plugin/public'; + +import type { UserProfileData } from './user_profile'; +import type { UserProfileAPIClient } from './user_profile_api_client'; + +interface Deps { + apiClient: UserProfileAPIClient; + notifications: NotificationsStart; +} + +interface Props { + notificationSuccess?: { + /** Flag to indicate if a notification is shown after update. Default: `true` */ + enabled?: boolean; + /** Customize the title of the notification */ + title?: string; + /** Customize the "page reload needed" text of the notification */ + pageReloadText?: string; + }; + /** Predicate to indicate if the update requires a page reload */ + pageReloadChecker?: ( + previsous: UserProfileData | null | undefined, + next: UserProfileData + ) => boolean; +} + +export type UpdateUserProfileHook = (props?: Props) => { + /** Update the user profile */ + update: (data: UserProfileData) => void; + /** Handler to show a notification after the user profile has been updated */ + showSuccessNotification: (props: { isRefreshRequired: boolean }) => void; + /** Flag to indicate if currently updating */ + isLoading: boolean; + /** The current user profile data */ + userProfileData?: UserProfileData | null; +}; + +const i18nTexts = { + notificationSuccess: { + title: i18n.translate('xpack.security.accountManagement.userProfile.submitSuccessTitle', { + defaultMessage: 'Profile updated', + }), + pageReloadText: i18n.translate( + 'xpack.security.accountManagement.userProfile.requiresPageReloadToastDescription', + { + defaultMessage: 'One or more settings require you to reload the page to take effect.', + } + ), + }, +}; + +export const getUseUpdateUserProfile = ({ apiClient, notifications }: Deps) => { + const { userProfile$ } = apiClient; + + const useUpdateUserProfile = ({ notificationSuccess = {}, pageReloadChecker }: Props = {}) => { + const { + enabled: notificationSuccessEnabled = true, + title: notificationTitle = i18nTexts.notificationSuccess.title, + pageReloadText = i18nTexts.notificationSuccess.pageReloadText, + } = notificationSuccess; + const [isLoading, setIsLoading] = useState(false); + const userProfileData = useObservable(userProfile$); + // Keep a snapshot before updating the user profile so we can compare previous and updated values + const userProfileSnapshot = useRef(); + + const showSuccessNotification = useCallback( + ({ isRefreshRequired = false }: { isRefreshRequired?: boolean } = {}) => { + let successToastInput: ToastInput = { + title: notificationTitle, + }; + let successToastOptions: ToastOptions = {}; + + if (isRefreshRequired) { + successToastOptions = { + toastLifeTimeMs: 1000 * 60 * 5, + }; + + successToastInput = { + ...successToastInput, + text: toMountPoint( + + +

{pageReloadText}

+ window.location.reload()} + data-test-subj="windowReloadButton" + > + {i18n.translate( + 'xpack.security.accountManagement.userProfile.requiresPageReloadToastButtonLabel', + { + defaultMessage: 'Reload page', + } + )} + +
+
+ ), + }; + } + + notifications.toasts.addSuccess(successToastInput, successToastOptions); + }, + [notificationTitle, pageReloadText] + ); + + const onUserProfileUpdate = useCallback( + (updatedData: UserProfileData) => { + setIsLoading(false); + + if (notificationSuccessEnabled) { + const isRefreshRequired = pageReloadChecker?.(userProfileSnapshot.current, updatedData); + showSuccessNotification({ isRefreshRequired }); + } + }, + [notificationSuccessEnabled, showSuccessNotification, pageReloadChecker] + ); + + const update = useCallback( + (udpatedData: D) => { + userProfileSnapshot.current = userProfileData; + setIsLoading(true); + return apiClient.update(udpatedData).then(() => onUserProfileUpdate(udpatedData)); + }, + [onUserProfileUpdate, userProfileData] + ); + + return { + update, + showSuccessNotification, + userProfileData, + isLoading, + }; + }; + + return useUpdateUserProfile; +}; diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx b/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx index fd7de9a7047f3..e9bb4b23af997 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx @@ -34,20 +34,24 @@ import type { FunctionComponent } from 'react'; import React, { useRef, useState } from 'react'; import useUpdateEffect from 'react-use/lib/useUpdateEffect'; -import type { CoreStart, IUiSettingsClient, ToastInput, ToastOptions } from '@kbn/core/public'; +import type { CoreStart, IUiSettingsClient } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { toMountPoint, useKibana } from '@kbn/kibana-react-plugin/public'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; import { UserAvatar } from '@kbn/user-profile-components'; -import type { AuthenticatedUser, UserProfileAvatarData } from '../../../common'; +import type { AuthenticatedUser } from '../../../common'; import { canUserChangeDetails, canUserChangePassword, getUserAvatarColor, getUserAvatarInitials, } from '../../../common/model'; -import type { UserSettingsData } from '../../../common/model/user_profile'; +import type { + DarkModeValue, + UserProfileAvatarData, + UserSettingsData, +} from '../../../common/model/user_profile'; import { useSecurityApiClients } from '../../components'; import { Breadcrumb } from '../../components/breadcrumb'; import { @@ -60,14 +64,18 @@ import { FormLabel } from '../../components/form_label'; import { FormRow, OptionalText } from '../../components/form_row'; import { ChangePasswordModal } from '../../management/users/edit_user/change_password_modal'; import { isUserReserved } from '../../management/users/user_utils'; +import { getUseUpdateUserProfile } from './use_update_user_profile'; import { createImageHandler, getRandomColor, IMAGE_FILE_TYPES, VALID_HEX_COLOR } from './utils'; +export interface UserProfileData { + avatar?: UserProfileAvatarData; + userSettings?: UserSettingsData; + [key: string]: unknown; +} + export interface UserProfileProps { user: AuthenticatedUser; - data?: { - avatar?: UserProfileAvatarData; - userSettings?: UserSettingsData; - }; + data?: UserProfileData; } export interface UserDetailsEditorProps { @@ -96,7 +104,7 @@ export interface UserProfileFormValues { imageUrl: string; }; userSettings: { - darkMode: string; + darkMode: DarkModeValue; }; }; avatarType: 'initials' | 'image'; @@ -815,6 +823,11 @@ export function useUserProfileForm({ user, data }: UserProfileProps) { const { services } = useKibana(); const { userProfiles, users } = useSecurityApiClients(); + const { update, showSuccessNotification } = getUseUpdateUserProfile({ + apiClient: userProfiles, + notifications: services.notifications, + })({ notificationSuccess: { enabled: false } }); + const [initialValues, resetInitialValues] = useState({ user: { full_name: user.full_name || '', @@ -855,7 +868,7 @@ export function useUserProfileForm({ user, data }: UserProfileProps) { // Update profile only if it's available for the current user. if (values.data) { submitActions.push( - userProfiles.update( + update( values.avatarType === 'image' ? values.data : { ...values.data, avatar: { ...values.data.avatar, imageUrl: null } } @@ -878,59 +891,13 @@ export function useUserProfileForm({ user, data }: UserProfileProps) { return; } + resetInitialValues(values); + let isRefreshRequired = false; if (initialValues.data?.userSettings.darkMode !== values.data?.userSettings.darkMode) { isRefreshRequired = true; } - - resetInitialValues(values); - - let successToastInput: ToastInput = { - title: i18n.translate('xpack.security.accountManagement.userProfile.submitSuccessTitle', { - defaultMessage: 'Profile updated', - }), - }; - - let successToastOptions: ToastOptions = {}; - - if (isRefreshRequired) { - successToastOptions = { - toastLifeTimeMs: 1000 * 60 * 5, - }; - - successToastInput = { - ...successToastInput, - text: toMountPoint( - - -

- {i18n.translate( - 'xpack.security.accountManagement.userProfile.requiresPageReloadToastDescription', - { - defaultMessage: - 'One or more settings require you to reload the page to take effect.', - } - )} -

- window.location.reload()} - data-test-subj="windowReloadButton" - > - {i18n.translate( - 'xpack.security.accountManagement.userProfile.requiresPageReloadToastButtonLabel', - { - defaultMessage: 'Reload page', - } - )} - -
-
- ), - }; - } - - services.notifications.toasts.addSuccess(successToastInput, successToastOptions); + showSuccessNotification({ isRefreshRequired }); }, initialValues, enableReinitialize: true, diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.test.ts b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.test.ts index 4fdb482a2cbae..0c275db2c1a90 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.test.ts +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.test.ts @@ -14,6 +14,7 @@ describe('UserProfileAPIClient', () => { let apiClient: UserProfileAPIClient; beforeEach(() => { coreStart = coreMock.createStart(); + coreStart.http.get.mockResolvedValue(undefined); coreStart.http.post.mockResolvedValue(undefined); apiClient = new UserProfileAPIClient(coreStart.http); diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts index a2fc60f7b4d75..4b992f616ca14 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts @@ -5,12 +5,14 @@ * 2.0. */ +import { merge } from 'lodash'; import type { Observable } from 'rxjs'; -import { Subject } from 'rxjs'; +import { BehaviorSubject, Subject } from 'rxjs'; import type { HttpStart } from '@kbn/core/public'; -import type { GetUserProfileResponse, UserProfile, UserProfileData } from '../../../common'; +import type { GetUserProfileResponse, UserProfile } from '../../../common'; +import type { UserProfileData } from './user_profile'; /** * Parameters for the get user profile for the current user API. @@ -70,6 +72,11 @@ export class UserProfileAPIClient { public readonly dataUpdates$: Observable = this.internalDataUpdates$.asObservable(); + private readonly _userProfile$ = new BehaviorSubject(null); + + /** Observable of the current user profile data */ + public readonly userProfile$ = this._userProfile$.asObservable(); + constructor(private readonly http: HttpStart) {} /** @@ -80,9 +87,16 @@ export class UserProfileAPIClient { * optional "dataPath" parameter can be used to return personal data for this user. */ public getCurrent(params?: UserProfileGetCurrentParams) { - return this.http.get>('/internal/security/user_profile', { - query: { dataPath: params?.dataPath }, - }); + return this.http + .get>('/internal/security/user_profile', { + query: { dataPath: params?.dataPath }, + }) + .then((response) => { + const data = response?.data ?? {}; + const updated = merge(this._userProfile$.getValue(), data); + this._userProfile$.next(updated); + return response; + }); } /** @@ -126,10 +140,19 @@ export class UserProfileAPIClient { * @param data Application data to be written (merged with existing data). */ public update(data: D) { + // Optimistic update the user profile Observable. + const previous = this._userProfile$.getValue(); + this._userProfile$.next(data); + return this.http .post('/internal/security/user_profile/_data', { body: JSON.stringify(data) }) .then(() => { this.internalDataUpdates$.next(data); + }) + .catch((err) => { + // Revert the user profile data to the previous state. + this._userProfile$.next(previous); + return Promise.reject(err); }); } } diff --git a/x-pack/plugins/security/public/index.ts b/x-pack/plugins/security/public/index.ts index 209bc5ff576b6..b51bb3d25092e 100644 --- a/x-pack/plugins/security/public/index.ts +++ b/x-pack/plugins/security/public/index.ts @@ -24,6 +24,7 @@ export type { UserProfileBulkGetParams, UserProfileGetCurrentParams, UserProfileSuggestParams, + UpdateUserProfileHook, } from './account_management'; export type { AuthenticationServiceStart, AuthenticationServiceSetup } from './authentication'; diff --git a/x-pack/plugins/security/public/mocks.ts b/x-pack/plugins/security/public/mocks.ts index e776d55f17d06..f0081307ef33f 100644 --- a/x-pack/plugins/security/public/mocks.ts +++ b/x-pack/plugins/security/public/mocks.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { of } from 'rxjs'; + import { licenseMock } from '../common/licensing/index.mock'; import type { MockAuthenticatedUserProps } from '../common/model/authenticated_user.mock'; import { mockAuthenticatedUser } from '../common/model/authenticated_user.mock'; @@ -22,8 +24,17 @@ function createStartMock() { return { authc: authenticationMock.createStart(), navControlService: navControlServiceMock.createStart(), - userProfiles: { getCurrent: jest.fn(), bulkGet: jest.fn(), suggest: jest.fn() }, + userProfiles: { + getCurrent: jest.fn(), + bulkGet: jest.fn(), + suggest: jest.fn(), + update: jest.fn(), + userProfile$: of({}), + }, uiApi: getUiApiMock.createStart(), + hooks: { + useUpdateUserProfile: jest.fn(), + }, }; } diff --git a/x-pack/plugins/security/public/nav_control/nav_control_component.test.tsx b/x-pack/plugins/security/public/nav_control/nav_control_component.test.tsx index 2936f705b75a2..a0f9df820c91e 100644 --- a/x-pack/plugins/security/public/nav_control/nav_control_component.test.tsx +++ b/x-pack/plugins/security/public/nav_control/nav_control_component.test.tsx @@ -166,6 +166,8 @@ describe('SecurityNavControl', () => { }); it('should render additional user menu links registered by other plugins and should render the default Edit Profile link as the first link when no custom profile link is provided', async () => { + const DummyComponent = () =>
Dummy Component
; + const wrapper = shallow( { { label: 'link1', href: 'path-to-link-1', iconType: 'empty', order: 1 }, { label: 'link2', href: 'path-to-link-2', iconType: 'empty', order: 2 }, { label: 'link3', href: 'path-to-link-3', iconType: 'empty', order: 3 }, + { + label: 'dummyComponent', + href: '', + iconType: 'empty', + order: 4, + content: DummyComponent, + }, ]) } /> @@ -183,63 +192,80 @@ describe('SecurityNavControl', () => { expect(wrapper.find(EuiContextMenu).prop('panels')).toMatchInlineSnapshot(` Array [ Object { + "content": , + "name": , + "onClick": [Function], + }, + Object { + "content": undefined, + "data-test-subj": "userMenuLink__link1", + "href": "path-to-link-1", + "icon": , + "name": "link1", + }, + Object { + "content": undefined, + "data-test-subj": "userMenuLink__link2", + "href": "path-to-link-2", + "icon": , + "name": "link2", + }, + Object { + "content": undefined, + "data-test-subj": "userMenuLink__link3", + "href": "path-to-link-3", + "icon": , + "name": "link3", + }, + Object { + "content": [Function], + "data-test-subj": "userMenuLink__dummyComponent", + "href": "", + "icon": , + "name": "dummyComponent", + }, + Object { + "data-test-subj": "logoutLink", + "href": "", + "icon": , + "name": , + }, + ] + } + />, "id": 0, - "items": Array [ - Object { - "data-test-subj": "profileLink", - "href": "edit-profile-link", - "icon": , - "name": , - "onClick": [Function], - }, - Object { - "data-test-subj": "userMenuLink__link1", - "href": "path-to-link-1", - "icon": , - "name": "link1", - }, - Object { - "data-test-subj": "userMenuLink__link2", - "href": "path-to-link-2", - "icon": , - "name": "link2", - }, - Object { - "data-test-subj": "userMenuLink__link3", - "href": "path-to-link-3", - "icon": , - "name": "link3", - }, - Object { - "data-test-subj": "logoutLink", - "href": "", - "icon": , - "name": , - }, - ], "title": "full name", }, ] @@ -270,49 +296,56 @@ describe('SecurityNavControl', () => { expect(wrapper.find(EuiContextMenu).prop('panels')).toMatchInlineSnapshot(` Array [ Object { + "content": , + "name": "link1", + }, + Object { + "content": undefined, + "data-test-subj": "userMenuLink__link2", + "href": "path-to-link-2", + "icon": , + "name": "link2", + }, + Object { + "content": undefined, + "data-test-subj": "userMenuLink__link3", + "href": "path-to-link-3", + "icon": , + "name": "link3", + }, + Object { + "data-test-subj": "logoutLink", + "href": "", + "icon": , + "name": , + }, + ] + } + />, "id": 0, - "items": Array [ - Object { - "data-test-subj": "userMenuLink__link1", - "href": "path-to-link-1", - "icon": , - "name": "link1", - }, - Object { - "data-test-subj": "userMenuLink__link2", - "href": "path-to-link-2", - "icon": , - "name": "link2", - }, - Object { - "data-test-subj": "userMenuLink__link3", - "href": "path-to-link-3", - "icon": , - "name": "link3", - }, - Object { - "data-test-subj": "logoutLink", - "href": "", - "icon": , - "name": , - }, - ], "title": "full name", }, ] @@ -340,22 +373,26 @@ describe('SecurityNavControl', () => { expect(wrapper.find(EuiContextMenu).prop('panels')).toMatchInlineSnapshot(` Array [ Object { + "content": , + "name": , + }, + ] + } + />, "id": 0, - "items": Array [ - Object { - "data-test-subj": "logoutLink", - "href": "", - "icon": , - "name": , - }, - ], "title": "full name", }, ] diff --git a/x-pack/plugins/security/public/nav_control/nav_control_component.tsx b/x-pack/plugins/security/public/nav_control/nav_control_component.tsx index 03f162c28dcf7..4a5e8ad545d64 100644 --- a/x-pack/plugins/security/public/nav_control/nav_control_component.tsx +++ b/x-pack/plugins/security/public/nav_control/nav_control_component.tsx @@ -8,13 +8,15 @@ import type { EuiContextMenuPanelItemDescriptor, IconType } from '@elastic/eui'; import { EuiContextMenu, + EuiContextMenuItem, + EuiContextMenuPanel, EuiHeaderSectionItemButton, EuiIcon, EuiLoadingSpinner, EuiPopover, } from '@elastic/eui'; -import type { FunctionComponent } from 'react'; -import React, { useState } from 'react'; +import type { FunctionComponent, ReactNode } from 'react'; +import React, { Fragment, useState } from 'react'; import useObservable from 'react-use/lib/useObservable'; import type { Observable } from 'rxjs'; @@ -32,8 +34,41 @@ export interface UserMenuLink { href: string; order?: number; setAsProfile?: boolean; + /** Render a custom ReactNode instead of the default */ + content?: ReactNode; } +type ContextMenuItem = EuiContextMenuPanelItemDescriptor & { content?: ReactNode }; + +interface ContextMenuProps { + items: ContextMenuItem[]; +} + +const ContextMenuContent = ({ items }: ContextMenuProps) => { + return ( + <> + + {items.map((item, i) => { + if (item.content) { + return {item.content}; + } + return ( + + {item.name} + + ); + })} + + + ); +}; + interface SecurityNavControlProps { editProfileUrl: string; logoutUrl: string; @@ -48,7 +83,7 @@ export const SecurityNavControl: FunctionComponent = ({ const userMenuLinks = useObservable(userMenuLinks$, []); const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const userProfile = useUserProfile<{ avatar: UserProfileAvatarData }>('avatar'); + const userProfile = useUserProfile<{ avatar: UserProfileAvatarData }>('avatar,userSettings'); const currentUser = useCurrentUser(); // User profiles do not exist for anonymous users so need to fetch current user as well const displayName = currentUser.value ? getUserDisplayName(currentUser.value) : ''; @@ -80,15 +115,16 @@ export const SecurityNavControl: FunctionComponent = ({ ); - const items: EuiContextMenuPanelItemDescriptor[] = []; + const items: ContextMenuItem[] = []; if (userMenuLinks.length) { const userMenuLinkMenuItems = userMenuLinks .sort(({ order: orderA = Infinity }, { order: orderB = Infinity }) => orderA - orderB) - .map(({ label, iconType, href }: UserMenuLink) => ({ + .map(({ label, iconType, href, content }: UserMenuLink) => ({ name: label, icon: , href, 'data-test-subj': `userMenuLink__${label}`, + content, })); items.push(...userMenuLinkMenuItems); } @@ -153,7 +189,7 @@ export const SecurityNavControl: FunctionComponent = ({ { id: 0, title: displayName, - items, + content: , }, ]} /> diff --git a/x-pack/plugins/security/public/plugin.test.tsx b/x-pack/plugins/security/public/plugin.test.tsx index a63216fb93465..87ce15a19202d 100644 --- a/x-pack/plugins/security/public/plugin.test.tsx +++ b/x-pack/plugins/security/public/plugin.test.tsx @@ -96,6 +96,9 @@ describe('Security Plugin', () => { "areAPIKeysEnabled": [Function], "getCurrentUser": [Function], }, + "hooks": Object { + "useUpdateUserProfile": [Function], + }, "navControlService": Object { "addUserMenuLinks": [Function], "getUserMenuLinks$": [Function], @@ -110,6 +113,18 @@ describe('Security Plugin', () => { "bulkGet": [Function], "getCurrent": [Function], "suggest": [Function], + "update": [Function], + "userProfile$": Observable { + "source": BehaviorSubject { + "_value": null, + "closed": false, + "currentObservers": null, + "hasError": false, + "isStopped": false, + "observers": Array [], + "thrownError": null, + }, + }, }, } `); diff --git a/x-pack/plugins/security/public/plugin.tsx b/x-pack/plugins/security/public/plugin.tsx index 7928317ba4a77..631b7341fc3b3 100644 --- a/x-pack/plugins/security/public/plugin.tsx +++ b/x-pack/plugins/security/public/plugin.tsx @@ -24,7 +24,9 @@ import type { SpacesPluginStart } from '@kbn/spaces-plugin/public'; import type { SecurityLicense } from '../common/licensing'; import { SecurityLicenseService } from '../common/licensing'; +import type { UpdateUserProfileHook } from './account_management'; import { accountManagementApp, UserProfileAPIClient } from './account_management'; +import { getUseUpdateUserProfile } from './account_management/user_profile/use_update_user_profile'; import { AnalyticsService } from './analytics'; import { AnonymousAccessService } from './anonymous_access'; import type { AuthenticationServiceSetup, AuthenticationServiceStart } from './authentication'; @@ -207,6 +209,16 @@ export class SecurityPlugin suggest: this.securityApiClients.userProfiles.suggest.bind( this.securityApiClients.userProfiles ), + update: this.securityApiClients.userProfiles.update.bind( + this.securityApiClients.userProfiles + ), + userProfile$: this.securityApiClients.userProfiles.userProfile$, + }, + hooks: { + useUpdateUserProfile: getUseUpdateUserProfile({ + apiClient: this.securityApiClients.userProfiles, + notifications: core.notifications, + }), }, }; } @@ -247,7 +259,17 @@ export interface SecurityPluginStart { /** * A set of methods to work with Kibana user profiles. */ - userProfiles: Pick; + userProfiles: Pick< + UserProfileAPIClient, + 'getCurrent' | 'bulkGet' | 'suggest' | 'update' | 'userProfile$' + >; + + /** + * A set of hooks to work with Kibana user profiles + */ + hooks: { + useUpdateUserProfile: UpdateUserProfileHook; + }; /** * Exposes UI components that will be loaded asynchronously. diff --git a/x-pack/plugins/security/server/lib/flatten_object.test.ts b/x-pack/plugins/security/server/lib/flatten_object.test.ts new file mode 100644 index 0000000000000..a69c7401154a1 --- /dev/null +++ b/x-pack/plugins/security/server/lib/flatten_object.test.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { flattenObject } from './flatten_object'; + +describe('FlattenObject', () => { + it('flattens multi level item', () => { + const data = { + foo: { + item1: 'value 1', + item2: { itemA: 'value 2' }, + }, + bar: { + item3: { itemA: { itemAB: 'value AB' } }, + item4: 'value 4', + item5: [1], + item6: [1, 2, 3], + }, + }; + + const flatten = flattenObject(data); + expect(flatten).toEqual({ + 'bar.item3.itemA.itemAB': 'value AB', + 'bar.item4': 'value 4', + 'bar.item5': 1, + 'bar.item6.0': 1, + 'bar.item6.1': 2, + 'bar.item6.2': 3, + 'foo.item1': 'value 1', + 'foo.item2.itemA': 'value 2', + }); + }); + + it('returns an empty object if no valid object is provided', () => { + expect(flattenObject({})).toEqual({}); + expect(flattenObject(null)).toEqual({}); + expect(flattenObject(undefined)).toEqual({}); + }); +}); diff --git a/x-pack/plugins/security/server/lib/flatten_object.ts b/x-pack/plugins/security/server/lib/flatten_object.ts new file mode 100644 index 0000000000000..45c0a3b6bbf13 --- /dev/null +++ b/x-pack/plugins/security/server/lib/flatten_object.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { compact, isObject } from 'lodash'; + +// Inspired by x-pack/plugins/apm/public/utils/flatten_object.ts +// Slighly modified to have key/value exposed as Object. +export const flattenObject = ( + item: Record | null | undefined, + accDefault: Record = {}, + parentKey?: string +): Record => { + if (item) { + const isArrayWithSingleValue = Array.isArray(item) && item.length === 1; + return Object.keys(item) + .sort() + .reduce>((acc, key) => { + const childKey = isArrayWithSingleValue ? '' : key; + const currentKey = compact([parentKey, childKey]).join('.'); + // item[key] can be a primitive (string, number, boolean, null, undefined) or Object or Array + if (isObject(item[key])) { + flattenObject(item[key], acc, currentKey); + } else { + acc[currentKey] = item[key]; + } + + return acc; + }, accDefault); + } + return {}; +}; diff --git a/x-pack/plugins/security/server/lib/index.ts b/x-pack/plugins/security/server/lib/index.ts index 1a1ae84e2af65..715eeb0955daa 100644 --- a/x-pack/plugins/security/server/lib/index.ts +++ b/x-pack/plugins/security/server/lib/index.ts @@ -11,3 +11,4 @@ export { validateKibanaPrivileges, transformPrivilegesToElasticsearchPrivileges, } from './role_utils'; +export { flattenObject } from './flatten_object'; diff --git a/x-pack/plugins/security/server/routes/user_profile/update.test.ts b/x-pack/plugins/security/server/routes/user_profile/update.test.ts index f358b65546d27..9165ee154cb78 100644 --- a/x-pack/plugins/security/server/routes/user_profile/update.test.ts +++ b/x-pack/plugins/security/server/routes/user_profile/update.test.ts @@ -132,6 +132,35 @@ describe('Update profile routes', () => { expect(userProfileService.update).not.toHaveBeenCalled(); }); + it('only allow specific user profile data keys to be updated for Elastic Cloud users.', async () => { + session.get.mockResolvedValue({ + error: null, + value: sessionMock.createValue({ userProfileId: 'u_some_id' }), + }); + authc.getCurrentUser.mockReturnValue(mockAuthenticatedUser({ elastic_cloud_user: true })); + + await expect( + routeHandler( + getMockContext(), + httpServerMock.createKibanaRequest({ + body: { + userSettings: { + darkMode: 'dark', // "userSettings.darkMode" is allowed + }, + }, + }), + kibanaResponseFactory + ) + ).resolves.toEqual(expect.objectContaining({ status: 200, payload: undefined })); + + expect(userProfileService.update).toBeCalledTimes(1); + expect(userProfileService.update).toBeCalledWith('u_some_id', { + userSettings: { + darkMode: 'dark', + }, + }); + }); + it('updates profile.', async () => { session.get.mockResolvedValue({ error: null, diff --git a/x-pack/plugins/security/server/routes/user_profile/update.ts b/x-pack/plugins/security/server/routes/user_profile/update.ts index 46df35eec036c..205f6a6d68a4a 100644 --- a/x-pack/plugins/security/server/routes/user_profile/update.ts +++ b/x-pack/plugins/security/server/routes/user_profile/update.ts @@ -9,9 +9,13 @@ import { schema } from '@kbn/config-schema'; import type { RouteDefinitionParams } from '..'; import { wrapIntoCustomErrorResponse } from '../../errors'; +import { flattenObject } from '../../lib'; import { getPrintableSessionId } from '../../session_management'; import { createLicensedRouteHandler } from '../licensed_route_handler'; +/** User profile data keys that are allowed to be updated by Cloud users */ +const ALLOWED_KEYS_UPDATE_CLOUD = ['userSettings.darkMode']; + export function defineUpdateUserProfileDataRoute({ router, getSession, @@ -43,18 +47,27 @@ export function defineUpdateUserProfileDataRoute({ } const currentUser = getAuthenticationService().getCurrentUser(request); + const userProfileData = request.body; + const keysToUpdate = Object.keys(flattenObject(userProfileData)); + if (currentUser?.elastic_cloud_user) { - logger.warn( - `Elastic Cloud SSO users aren't allowed to update profiles in Kibana. (sid: ${getPrintableSessionId( - session.value.sid - )})` + // We only allow specific user profile data to be updated by Elastic Cloud SSO users. + const isUpdateAllowed = keysToUpdate.every((key) => + ALLOWED_KEYS_UPDATE_CLOUD.includes(key) ); - return response.forbidden(); + if (keysToUpdate.length === 0 || !isUpdateAllowed) { + logger.warn( + `Elastic Cloud SSO users aren't allowed to update profiles in Kibana. (sid: ${getPrintableSessionId( + session.value.sid + )})` + ); + return response.forbidden(); + } } const userProfileService = getUserProfileService(); try { - await userProfileService.update(session.value.userProfileId, request.body); + await userProfileService.update(session.value.userProfileId, userProfileData); return response.ok(); } catch (error) { return response.customError(wrapIntoCustomErrorResponse(error)); diff --git a/x-pack/test/functional_cloud/tests/cloud_links.ts b/x-pack/test/functional_cloud/tests/cloud_links.ts index 743df23740fb4..873cd943ec59d 100644 --- a/x-pack/test/functional_cloud/tests/cloud_links.ts +++ b/x-pack/test/functional_cloud/tests/cloud_links.ts @@ -72,6 +72,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const cloudLink = await find.byLinkText('Organization'); expect(cloudLink).to.not.be(null); }); + + it('Shows the theme darkMode toggle', async () => { + await PageObjects.common.clickAndValidate('userMenuButton', 'darkModeToggle'); + const darkModeSwitch = await find.byCssSelector('[data-test-subj="darkModeToggleSwitch"]'); + expect(darkModeSwitch).to.not.be(null); + }); }); }); } From ccb36d929a2514dfce82534471455480e335e206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Wed, 12 Jul 2023 17:19:00 +0200 Subject: [PATCH 75/97] [APM] Fix broken unit tests (#161636) A bunch of APM unit tests were passing on CI but failing locally. This PR fixes the unit tests **Why fail locally and pass on CI??** The reason they pass on CI is because `console.error` calls are omitted. In the APM jest config `console.error` is treated as a test failure: https://github.com/elastic/kibana/blob/7ea0dd6b116a93024d68ea2d93fa4ce90e9bf189/x-pack/plugins/apm/jest_setup.js#L12-L15 --- .../error_count_rule_type/index.stories.tsx | 13 ++++++++----- .../components/app/service_map/index.test.tsx | 5 +++-- .../transaction_overview.test.tsx | 10 ++++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/apm/public/components/alerting/rule_types/error_count_rule_type/index.stories.tsx b/x-pack/plugins/apm/public/components/alerting/rule_types/error_count_rule_type/index.stories.tsx index 424e490b732b1..ddcae65209f67 100644 --- a/x-pack/plugins/apm/public/components/alerting/rule_types/error_count_rule_type/index.stories.tsx +++ b/x-pack/plugins/apm/public/components/alerting/rule_types/error_count_rule_type/index.stories.tsx @@ -10,6 +10,7 @@ import React, { useState } from 'react'; import { CoreStart } from '@kbn/core/public'; import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; import { TIME_UNITS } from '@kbn/triggers-actions-ui-plugin/public'; +import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { RuleParams, ErrorCountRuleType } from '.'; import { ENVIRONMENT_ALL } from '../../../../../common/environment_filter_values'; import { createCallApmApi } from '../../../../services/rest/create_call_apm_api'; @@ -36,11 +37,13 @@ const stories: Meta<{}> = { createCallApmApi(coreMock); return ( - -
- -
-
+ + +
+ +
+
+
); }, ], diff --git a/x-pack/plugins/apm/public/components/app/service_map/index.test.tsx b/x-pack/plugins/apm/public/components/app/service_map/index.test.tsx index b844ff2cff098..2fe42bd7692bd 100644 --- a/x-pack/plugins/apm/public/components/app/service_map/index.test.tsx +++ b/x-pack/plugins/apm/public/components/app/service_map/index.test.tsx @@ -6,7 +6,7 @@ */ import { render } from '@testing-library/react'; -import { createMemoryHistory } from 'history'; +import { createMemoryHistory, MemoryHistory } from 'history'; import { CoreStart } from '@kbn/core/public'; import React, { ReactNode } from 'react'; import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; @@ -18,7 +18,7 @@ import * as useFetcherModule from '../../../hooks/use_fetcher'; import { ServiceMap } from '.'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; -const history = createMemoryHistory(); +let history: MemoryHistory; const KibanaReactContext = createKibanaReactContext({ usageCollection: { reportUiCounter: () => {} }, @@ -47,6 +47,7 @@ const expiredLicense = new License({ }); function createWrapper(license: License | null) { + history = createMemoryHistory(); history.replace('/service-map?rangeFrom=now-15m&rangeTo=now'); return ({ children }: { children?: ReactNode }) => { diff --git a/x-pack/plugins/apm/public/components/app/transaction_overview/transaction_overview.test.tsx b/x-pack/plugins/apm/public/components/app/transaction_overview/transaction_overview.test.tsx index bf144507ce867..79db66bcb5d43 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_overview/transaction_overview.test.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_overview/transaction_overview.test.tsx @@ -6,7 +6,7 @@ */ import { queryByLabelText } from '@testing-library/react'; -import { createMemoryHistory } from 'history'; +import { createMemoryHistory, MemoryHistory } from 'history'; import { CoreStart } from '@kbn/core/public'; import React from 'react'; import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public'; @@ -32,9 +32,7 @@ const KibanaReactContext = createKibanaReactContext({ usageCollection: { reportUiCounter: () => {} }, } as unknown as Partial); -const history = createMemoryHistory(); -jest.spyOn(history, 'push'); -jest.spyOn(history, 'replace'); +let history: MemoryHistory; function setup({ urlParams, @@ -43,6 +41,10 @@ function setup({ urlParams: ApmUrlParams; serviceTransactionTypes: string[]; }) { + history = createMemoryHistory(); + jest.spyOn(history, 'push'); + jest.spyOn(history, 'replace'); + history.replace({ pathname: '/services/foo/transactions', search: fromQuery(urlParams), From 130e9deea59a326e1e0d40827ad7a0bc401a3d27 Mon Sep 17 00:00:00 2001 From: Wafaa Nasr Date: Wed, 12 Jul 2023 16:50:02 +0100 Subject: [PATCH 76/97] [Security Solution] Fixing exceptions flyout is not auto filled with all highlighted fields listed on Alert details page (#161673) ## Summary - Addresses https://github.com/elastic/kibana/issues/161460 - Exclude `agent.id` in case the Alert's `agent.type` is not `endpoint` - Handle Alert `event.category` array field ex. `[process]` - For the `Threshold Rule` there are two additional fields the Alert Summary populates the `Event Count` and the `Event Cardinality` which can be ignored as they are not relevant to the Rule exception ![image](https://github.com/elastic/kibana/assets/12671903/8972a647-6490-4d54-8af8-54f90d4ac438) ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../rule_exceptions/utils/helpers.test.tsx | 43 +++++++++++++++++-- .../rule_exceptions/utils/helpers.tsx | 33 ++++++++++++-- .../utils/highlighted_fields_config.ts | 4 ++ 3 files changed, 73 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/helpers.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/helpers.test.tsx index 26534402400ea..509133110554f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/helpers.test.tsx @@ -51,6 +51,7 @@ import { ALERT_ORIGINAL_EVENT_KIND, ALERT_ORIGINAL_EVENT_MODULE, } from '../../../../common/field_maps/field_names'; +import { AGENT_ID } from './highlighted_fields_config'; jest.mock('uuid', () => ({ v4: jest.fn().mockReturnValue('123'), })); @@ -1528,6 +1529,7 @@ describe('Exception helpers', () => { 'event.category': 'malware', 'event.type': 'creation', 'event.dataset': 'endpoint', + 'kibana.alert.rule.uuid': '123', 'kibana.alert.rule.exceptions_list': [ { id: 'endpoint_list', @@ -1714,17 +1716,18 @@ describe('Exception helpers', () => { describe('filterHighlightedFields', () => { const prefixesToExclude = ['agent', 'cloud']; it('should not filter any field if no prefixes passed ', () => { - const filteredFields = filterHighlightedFields(expectedHighlightedFields, []); + const filteredFields = filterHighlightedFields(expectedHighlightedFields, [], alertData); expect(filteredFields).toEqual(expectedHighlightedFields); }); it('should not filter any field if no fields passed ', () => { - const filteredFields = filterHighlightedFields([], prefixesToExclude); + const filteredFields = filterHighlightedFields([], prefixesToExclude, alertData); expect(filteredFields).toEqual([]); }); it('should filter out the passed prefixes successfully', () => { const filteredFields = filterHighlightedFields( expectedHighlightedFields, - prefixesToExclude + prefixesToExclude, + alertData ); expect(filteredFields).not.toEqual( expect.arrayContaining([ @@ -1845,6 +1848,24 @@ describe('Exception helpers', () => { }, ]); }); + it('should return the process highlighted fields correctly when eventCategory is an array', () => { + const alertDataEventCategoryProcessArray = { ...alertData, 'event.category': ['process'] }; + const res = getAlertHighlightedFields(alertDataEventCategoryProcessArray); + expect(res).not.toEqual( + expect.arrayContaining([ + { id: 'file.name' }, + { id: 'file.hash.sha256' }, + { id: 'file.directory' }, + ]) + ); + expect(res).toEqual( + expect.arrayContaining([ + { id: 'process.name' }, + { id: 'process.parent.name' }, + { id: 'process.args' }, + ]) + ); + }); it('should return all highlighted fields even when the "kibana.alert.rule.type" is not in the alertData', () => { const alertDataWithoutEventCategory = { ...alertData, 'kibana.alert.rule.type': null }; const res = getAlertHighlightedFields(alertDataWithoutEventCategory); @@ -1856,6 +1877,22 @@ describe('Exception helpers', () => { const res = getAlertHighlightedFields(alertData); expect(res).toEqual(allHighlightFields); }); + it('should exclude the "agent.id" from highlighted fields when agent.type is not "endpoint"', () => { + jest.mock('./highlighted_fields_config', () => ({ highlightedFieldsPrefixToExclude: [] })); + + const alertDataWithoutAgentType = { ...alertData, agent: { ...alertData.agent, type: '' } }; + const res = getAlertHighlightedFields(alertDataWithoutAgentType); + + expect(res).toEqual(allHighlightFields.filter((field) => field.id !== AGENT_ID)); + }); + it('should exclude the "agent.id" from highlighted fields when "kibana.alert.rule.uuid" is not part of the alertData', () => { + jest.mock('./highlighted_fields_config', () => ({ highlightedFieldsPrefixToExclude: [] })); + + const alertDataWithoutRuleUUID = { ...alertData, 'kibana.alert.rule.uuid': '' }; + const res = getAlertHighlightedFields(alertDataWithoutRuleUUID); + + expect(res).toEqual(allHighlightFields.filter((field) => field.id !== AGENT_ID)); + }); }); describe('getPrepopulatedRuleExceptionWithHighlightFields', () => { it('should not create any exception and return null if there are no highlighted fields', () => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/helpers.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/helpers.tsx index 396714258cd33..6104379845e2f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/helpers.tsx @@ -59,6 +59,10 @@ import { getKibanaAlertIdField, highlightedFieldsPrefixToExclude, KIBANA_ALERT_RULE_TYPE, + AGENT_ID, + AGENT_TYPE, + KIBANA_ALERT_RULE_UUID, + ENDPOINT_ALERT, } from './highlighted_fields_config'; export const filterIndexPatterns = ( @@ -958,13 +962,19 @@ export const getPrepopulatedRuleExceptionWithHighlightFields = ({ /** Filters out the irrelevant highlighted fields for Rule exceptions using - the "highlightedFieldsPrefixToExclude" array. + 1. The "highlightedFieldsPrefixToExclude" array + 2. Agent.id field in case the alert was not generated from Endpoint + 3. Threshold Rule */ export const filterHighlightedFields = ( fields: EventSummaryField[], - prefixesToExclude: string[] + prefixesToExclude: string[], + alertData: AlertData ): EventSummaryField[] => { return fields.filter(({ id }) => { + // Exclude agent.id field only if the agent type was not Endpoint + if (id === AGENT_ID) return isAlertFromEndpointEvent(alertData); + return !prefixesToExclude.some((field: string) => id.startsWith(field)); }); }; @@ -974,6 +984,7 @@ export const filterHighlightedFields = ( * * event.category * * event.code * * kibana.alert.rule.type + * * Alert field ids filters * @param alertData The Alert data object */ export const getAlertHighlightedFields = (alertData: AlertData): EventSummaryField[] => { @@ -982,7 +993,7 @@ export const getAlertHighlightedFields = (alertData: AlertData): EventSummaryFie const eventRuleType = get(alertData, KIBANA_ALERT_RULE_TYPE); const eventCategories = { - primaryEventCategory: eventCategory, + primaryEventCategory: Array.isArray(eventCategory) ? eventCategory[0] : eventCategory, allEventCategories: [eventCategory], }; @@ -991,5 +1002,19 @@ export const getAlertHighlightedFields = (alertData: AlertData): EventSummaryFie eventCode, eventRuleType, }); - return filterHighlightedFields(fieldsToDisplay, highlightedFieldsPrefixToExclude); + return filterHighlightedFields(fieldsToDisplay, highlightedFieldsPrefixToExclude, alertData); +}; + +/** + * Checks to see if the given set of Timeline event detail items includes data that indicates its + * an endpoint Alert + */ +export const isAlertFromEndpointEvent = (alertData: AlertData) => { + // Check to see if a timeline event item is an Alert + const isTimelineEventItemAnAlert = get(alertData, KIBANA_ALERT_RULE_UUID); + if (!isTimelineEventItemAnAlert) return false; + + const agentTypes = get(alertData, AGENT_TYPE); + const agentType = Array.isArray(agentTypes) ? agentTypes[0] : agentTypes; + return agentType === ENDPOINT_ALERT; }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/highlighted_fields_config.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/highlighted_fields_config.ts index 58c6c14b355ed..d4456c534050c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/highlighted_fields_config.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/highlighted_fields_config.ts @@ -18,3 +18,7 @@ export const getKibanaAlertIdField = (id: string) => `kibana.alert.${id}`; export const EVENT_CATEGORY = 'event.category'; export const EVENT_CODE = 'event.code'; export const KIBANA_ALERT_RULE_TYPE = 'kibana.alert.rule.type'; +export const AGENT_ID = 'agent.id'; +export const AGENT_TYPE = 'agent.type'; +export const KIBANA_ALERT_RULE_UUID = 'kibana.alert.rule.uuid'; +export const ENDPOINT_ALERT = 'endpoint'; From 7af4c38620cff7be57a4473f600d67a353835802 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 12 Jul 2023 12:04:22 -0400 Subject: [PATCH 77/97] skip failing test suite (#161557) --- x-pack/test/fleet_api_integration/apis/agents/upgrade.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts index 0c31fd5d710cc..0e2ebf5c9c9cc 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts @@ -21,7 +21,8 @@ export default function (providerContext: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const supertestWithoutAuth = getService('supertestWithoutAuth'); - describe('fleet_upgrade_agent', () => { + // Failing: See https://github.com/elastic/kibana/issues/161557 + describe.skip('fleet_upgrade_agent', () => { skipIfNoDockerRegistry(providerContext); before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/fleet/agents'); From 78700f369186fe3298f56026d4be2e3f06d00f41 Mon Sep 17 00:00:00 2001 From: christineweng <18648970+christineweng@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:37:14 -0500 Subject: [PATCH 78/97] [Security Solution] expandable flyout - open rule in new tab (#161708) ## Summary This PR updates the `View rule` button to open rule detail page in a new tab. This is option 1 of improving the UX experience on rules in expandable flyout ![image](https://github.com/elastic/kibana/assets/18648970/f7e94101-1524-475d-8aa7-7a7fec432457) --- ...ert_details_right_panel_overview_tab.cy.ts | 2 +- .../flyout/right/components/description.tsx | 13 +++---------- .../renderers/formatted_field_helpers.tsx | 19 ++++++++++++++----- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts index f570fb35e1e29..2f29461f5228f 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts @@ -100,7 +100,7 @@ describe( .within(() => { cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_NAVIGATE_TO_RULE_DETAILS_BUTTON) .should('be.visible') - .and('have.text', 'View rule'); + .and('contain.text', 'View rule'); }); cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_DETAILS) .should('be.visible') diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/description.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/description.tsx index 450f62d32079d..f8886f7d2f1f2 100644 --- a/x-pack/plugins/security_solution/public/flyout/right/components/description.tsx +++ b/x-pack/plugins/security_solution/public/flyout/right/components/description.tsx @@ -5,12 +5,11 @@ * 2.0. */ -import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiTitle, EuiIcon } from '@elastic/eui'; +import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui'; import type { VFC } from 'react'; import React, { useState, useMemo } from 'react'; import { css } from '@emotion/react'; import { isEmpty } from 'lodash'; -import styled from 'styled-components'; import { useRightPanelContext } from '../context'; import { useBasicDataFromDetailsData } from '../../../timelines/components/side_panel/event_details/helpers'; import { @@ -28,10 +27,6 @@ import { import { RenderRuleName } from '../../../timelines/components/timeline/body/renderers/formatted_field_helpers'; import { SIGNAL_RULE_NAME_FIELD_NAME } from '../../../timelines/components/timeline/body/renderers/constants'; -const StyledEuiIcon = styled(EuiIcon)` - margin-left: ${({ theme }) => theme.eui.euiSizeXS}; -`; - export interface DescriptionProps { /** * Boolean to allow the component to be expanded or collapsed on first render @@ -66,10 +61,8 @@ export const Description: VFC = ({ expanded = false }) => { isDraggable={false} linkValue={ruleId} value={VIEW_RULE_TEXT} - > - {VIEW_RULE_TEXT} - - + openInNewTab + /> ), [ruleName, ruleId, scopeId, eventId] diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field_helpers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field_helpers.tsx index e6ef10ea72fe1..536a57fa5159a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field_helpers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/renderers/formatted_field_helpers.tsx @@ -44,6 +44,7 @@ interface RenderRuleNameProps { isButton?: boolean; onClick?: () => void; linkValue: string | null | undefined; + openInNewTab?: boolean; truncate?: boolean; title?: string; value: string | number | null | undefined; @@ -61,6 +62,7 @@ export const RenderRuleName: React.FC = ({ isButton, onClick, linkValue, + openInNewTab = false, truncate, title, value, @@ -76,9 +78,10 @@ export const RenderRuleName: React.FC = ({ navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId ?? '', search), + openInNewTab, }); }, - [navigateToApp, ruleId, search] + [navigateToApp, ruleId, search, openInNewTab] ); const href = useMemo( @@ -121,16 +124,21 @@ export const RenderRuleName: React.FC = ({ {title ?? value} ); - } else if (children) { + } else if (openInNewTab) { return ( - - {children} + + {children ?? content} ); } else { return ( - {content} + {children ?? content} ); } @@ -146,6 +154,7 @@ export const RenderRuleName: React.FC = ({ title, truncate, value, + openInNewTab, ]); if (isString(value) && ruleName.length > 0 && ruleId != null) { From 7f3c9e8c811c0eff75a3d8d27ce337eeaddeded1 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Wed, 12 Jul 2023 09:56:57 -0700 Subject: [PATCH 79/97] [DOCS] Add rule.params to rule action variables (#161714) --- docs/user/alerting/action-variables.asciidoc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/user/alerting/action-variables.asciidoc b/docs/user/alerting/action-variables.asciidoc index 5e26dd874f67e..6fe275547004c 100644 --- a/docs/user/alerting/action-variables.asciidoc +++ b/docs/user/alerting/action-variables.asciidoc @@ -1,5 +1,9 @@ [[rule-action-variables]] == Rule action variables +:frontmatter-description: A summary of common variables for use in {kib} alerting rule actions. +:frontmatter-tags-products: [alerting] +:frontmatter-tags-content-type: [reference] +:frontmatter-tags-user-goals: [configure] Alerting rules can use the https://mustache.github.io/mustache.5.html[Mustache] template syntax (`{{variable name}}`) to pass values when the actions run. @@ -30,9 +34,10 @@ All rule types pass the following variables: `date`:: The date the rule scheduled the action, in ISO format. `kibanaBaseUrl`:: The configured <>. If not configured, this will be empty. -`rule.id`:: The ID of the rule. -`rule.name`:: The name of the rule. -`rule.spaceId`:: The ID of the space for the rule. +`rule.id`:: The rule identifier. +`rule.name`:: The rule name. +`rule.params`:: The rule parameters, which vary by rule type. +`rule.spaceId`:: The space identifier for the rule. `rule.tags`:: The list of tags applied to the rule. [float] From 8b72a32c138e9e6005fd5f70f632593d5369b136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Wed, 12 Jul 2023 18:15:18 +0100 Subject: [PATCH 80/97] [Chrome left nav] Fix infinite loop (#161773) --- .../src/chrome_service.tsx | 9 +------- .../chrome/navigation/src/services.tsx | 6 +----- .../src/ui/components/navigation_group.tsx | 18 +++++++++++----- .../src/ui/components/navigation_item.tsx | 11 ++++++++-- .../ui/components/navigation_section_ui.tsx | 18 +++++++++------- .../src/ui/components/recently_accessed.tsx | 21 +++++++++++++------ 6 files changed, 49 insertions(+), 34 deletions(-) diff --git a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx index d8a855804d47d..1141438304ca9 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx @@ -267,9 +267,6 @@ export class ChromeService { const getHeaderComponent = () => { if (chromeStyle$.getValue() === 'project') { const projectNavigationComponent$ = projectNavigation.getProjectSideNavComponent$(); - const projectNavigation$ = projectNavigation - .getProjectNavigation$() - .pipe(takeUntil(this.stop$)); const projectBreadcrumbs$ = projectNavigation .getProjectBreadcrumbs$() .pipe(takeUntil(this.stop$)); @@ -279,11 +276,7 @@ export class ChromeService { const CustomSideNavComponent = useObservable(projectNavigationComponent$, undefined); const activeNodes = useObservable(activeNodes$, []); - const currentProjectNavigation = useObservable(projectNavigation$, undefined); - // TODO: remove this switch once security sets project navigation tree - const currentProjectBreadcrumbs$ = currentProjectNavigation - ? projectBreadcrumbs$ - : breadcrumbs$; + const currentProjectBreadcrumbs$ = projectBreadcrumbs$; let SideNavComponent: ISideNavComponent = () => null; diff --git a/packages/shared-ux/chrome/navigation/src/services.tsx b/packages/shared-ux/chrome/navigation/src/services.tsx index d9b7f3804db1b..f59365b21ead3 100644 --- a/packages/shared-ux/chrome/navigation/src/services.tsx +++ b/packages/shared-ux/chrome/navigation/src/services.tsx @@ -40,11 +40,7 @@ export const NavigationKibanaProvider: FC = ({ activeNodes$: serverless.getActiveNavigationNodes$(), }; - return ( - - {children} - - ); + return {children}; }; /** diff --git a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_group.tsx b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_group.tsx index dcfa47d92d641..eda309b3635b2 100644 --- a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_group.tsx +++ b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_group.tsx @@ -46,11 +46,19 @@ function NavigationGroupInternalComp< ChildrenId extends string = Id >(props: Props) { const navigationContext = useNavigation(); - const { children, defaultIsCollapsed, ...node } = props; - const { navNode, registerChildNode, path, childrenNodes } = useInitNavNode({ - ...node, - isActive: defaultIsCollapsed !== undefined ? defaultIsCollapsed === false : undefined, - }); + + const { children, node } = useMemo(() => { + const { children: _children, defaultIsCollapsed, ...rest } = props; + return { + children: _children, + node: { + ...rest, + isActive: defaultIsCollapsed !== undefined ? defaultIsCollapsed === false : undefined, + }, + }; + }, [props]); + + const { navNode, registerChildNode, path, childrenNodes } = useInitNavNode(node); const unstyled = props.unstyled ?? navigationContext.unstyled; diff --git a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_item.tsx b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_item.tsx index a0564b7180970..4333db7c9844c 100644 --- a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_item.tsx +++ b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_item.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { Fragment, ReactElement, ReactNode, useEffect } from 'react'; +import React, { Fragment, ReactElement, ReactNode, useEffect, useMemo } from 'react'; import type { AppDeepLinkId } from '@kbn/core-chrome-browser'; import type { ChromeProjectNavigationNodeEnhanced, NodeProps } from '../types'; @@ -34,7 +34,14 @@ function NavigationItemComp< const navigationContext = useNavigation(); const navNodeRef = React.useRef(null); - const { element, children, ...node } = props; + const { element, children, node } = useMemo(() => { + const { element: _element, children: _children, ...rest } = props; + return { + element: _element, + children: _children, + node: rest, + }; + }, [props]); const unstyled = props.unstyled ?? navigationContext.unstyled; let renderItem: (() => ReactElement) | undefined; diff --git a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx index 9e3e8ec812b5c..12a4605d4837a 100644 --- a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx +++ b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { FC, useEffect, useRef, useState } from 'react'; +import React, { FC, useEffect, useState } from 'react'; import { EuiCollapsibleNavGroup, EuiIcon, @@ -80,7 +80,9 @@ export const NavigationSectionUI: FC = ({ navNode, items = [] }) => { const { id, title, icon, isActive } = navNode; const { navigateToUrl, basePath } = useServices(); const [isCollapsed, setIsCollapsed] = useState(!isActive); - const initialTime = useRef(Date.now()); + // We want to auto expand the group automatically if the node is active (URL match) + // but once the user manually expand a group we don't want to close it afterward automatically. + const [doCollapseFromActiveState, setDoCollapseFromActiveState] = useState(true); // If the item has no link and no cildren, we don't want to render it const itemHasLinkOrChildren = (item: ChromeProjectNavigationNodeEnhanced) => { @@ -108,13 +110,10 @@ export const NavigationSectionUI: FC = ({ navNode, items = [] }) => { const groupHasLink = Boolean(navNode.deepLink) || Boolean(navNode.href); useEffect(() => { - // We only want to set the collapsed state during the "mounting" phase (500ms). - // After that, even if the URL does not match the group and the group is open we don't - // want to collapse it automatically. - if (Date.now() - initialTime.current < 500) { + if (doCollapseFromActiveState) { setIsCollapsed(!isActive); } - }, [isActive]); + }, [isActive, doCollapseFromActiveState]); if (!groupHasLink && !filteredItems.some(itemHasLinkOrChildren)) { return null; @@ -127,7 +126,10 @@ export const NavigationSectionUI: FC = ({ navNode, items = [] }) => { iconType={icon} isCollapsible={true} initialIsOpen={isActive} - onToggle={(isOpen) => setIsCollapsed(!isOpen)} + onToggle={(isOpen) => { + setIsCollapsed(!isOpen); + setDoCollapseFromActiveState(false); + }} forceState={isCollapsed ? 'closed' : 'open'} data-test-subj={`nav-bucket-${id}`} > diff --git a/packages/shared-ux/chrome/navigation/src/ui/components/recently_accessed.tsx b/packages/shared-ux/chrome/navigation/src/ui/components/recently_accessed.tsx index b6bbff8904ed4..57e7b3dcfd058 100644 --- a/packages/shared-ux/chrome/navigation/src/ui/components/recently_accessed.tsx +++ b/packages/shared-ux/chrome/navigation/src/ui/components/recently_accessed.tsx @@ -31,7 +31,7 @@ export const RecentlyAccessed: FC = ({ defaultIsCollapsed = false, }) => { const strings = getI18nStrings(); - const { recentlyAccessed$ } = useServices(); + const { recentlyAccessed$, basePath, navigateToUrl } = useServices(); const recentlyAccessed = useObservable(recentlyAccessedProp$ ?? recentlyAccessed$, []); if (recentlyAccessed.length === 0) { @@ -42,11 +42,20 @@ export const RecentlyAccessed: FC = ({ { name: '', // no list header title id: 'recents_root', - items: recentlyAccessed.map(({ id, label, link }) => ({ - id, - name: label, - href: link, - })), + items: recentlyAccessed.map((recent) => { + const { id, label, link } = recent; + const href = basePath.prepend(link); + + return { + id, + name: label, + href, + onClick: (e: React.MouseEvent) => { + e.preventDefault(); + navigateToUrl(href); + }, + }; + }), }, ]; From c8bec1d07d09a714491711d3f0f0699b85394cbc Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Wed, 12 Jul 2023 13:17:19 -0400 Subject: [PATCH 81/97] [Fleet] Support local routing rules (#161573) --- .../plugins/fleet/common/types/models/epm.ts | 11 +++ .../server/services/epm/archive/parse.test.ts | 62 ++++++++++++- .../server/services/epm/archive/parse.ts | 56 ++++++++--- .../server/services/epm/archive/storage.ts | 12 ++- .../ingest_pipeline/helpers.test.ts | 93 ++++++++++++++++++- .../elasticsearch/ingest_pipeline/helpers.ts | 23 ++++- .../elasticsearch/ingest_pipeline/install.ts | 15 ++- .../elasticsearch/ingest_pipeline/types.ts | 3 + .../apis/epm/custom_ingest_pipeline.ts | 2 +- .../fleet_api_integration/apis/epm/index.js | 1 + .../apis/epm/routing_rules.ts | 87 +++++++++++++++++ .../1.0.0/data_stream/test/fields/fields.yml | 18 ++++ .../1.0.0/data_stream/test/manifest.yml | 6 ++ .../1.0.0/data_stream/test/routing_rules.yml | 9 ++ .../routing_rules/1.0.0/docs/README.md | 3 + .../routing_rules/1.0.0/img/logo.svg | 7 ++ .../routing_rules/1.0.0/manifest.yml | 25 +++++ 17 files changed, 396 insertions(+), 37 deletions(-) create mode 100644 x-pack/test/fleet_api_integration/apis/epm/routing_rules.ts create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/fields/fields.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/manifest.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/routing_rules.yml create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/docs/README.md create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/img/logo.svg create mode 100644 x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/manifest.yml diff --git a/x-pack/plugins/fleet/common/types/models/epm.ts b/x-pack/plugins/fleet/common/types/models/epm.ts index ec9f7f3d2fd42..dcff8ae3071e7 100644 --- a/x-pack/plugins/fleet/common/types/models/epm.ts +++ b/x-pack/plugins/fleet/common/types/models/epm.ts @@ -335,6 +335,7 @@ export enum RegistryDataStreamKeys { ingest_pipeline = 'ingest_pipeline', elasticsearch = 'elasticsearch', dataset_is_prefix = 'dataset_is_prefix', + routing_rules = 'routing_rules', } export interface RegistryDataStream { @@ -351,6 +352,7 @@ export interface RegistryDataStream { [RegistryDataStreamKeys.ingest_pipeline]?: string; [RegistryDataStreamKeys.elasticsearch]?: RegistryElasticsearch; [RegistryDataStreamKeys.dataset_is_prefix]?: boolean; + [RegistryDataStreamKeys.routing_rules]?: RegistryDataStreamRoutingRules[]; } export interface RegistryElasticsearch { @@ -374,6 +376,15 @@ export interface RegistryDataStreamPrivileges { indices?: string[]; } +export interface RegistryDataStreamRoutingRules { + source_dataset: string; + rules: Array<{ + target_dataset: string; + if: string; + namespace: string; + }>; +} + export type RegistryVarType = | 'integer' | 'bool' diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts index 504ec6f658a57..5848252a2972d 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.test.ts @@ -459,7 +459,7 @@ describe('parseAndVerifyDataStreams', () => { paths: ['input-only-0.1.0/data_stream/stream1/README.md'], pkgName: 'input-only', pkgVersion: '0.1.0', - manifests: {}, + manifestsAndRoutingRules: {}, }) ).toThrowError("No manifest.yml file found for data stream 'stream1'"); }); @@ -470,7 +470,7 @@ describe('parseAndVerifyDataStreams', () => { paths: ['input-only-0.1.0/data_stream/stream1/manifest.yml'], pkgName: 'input-only', pkgVersion: '0.1.0', - manifests: { + manifestsAndRoutingRules: { 'input-only-0.1.0/data_stream/stream1/manifest.yml': Buffer.alloc(1), }, }) @@ -483,7 +483,7 @@ describe('parseAndVerifyDataStreams', () => { paths: ['input-only-0.1.0/data_stream/stream1/manifest.yml'], pkgName: 'input-only', pkgVersion: '0.1.0', - manifests: { + manifestsAndRoutingRules: { 'input-only-0.1.0/data_stream/stream1/manifest.yml': Buffer.from( ` title: Custom Logs`, @@ -502,7 +502,7 @@ describe('parseAndVerifyDataStreams', () => { paths: ['input-only-0.1.0/data_stream/stream1/manifest.yml'], pkgName: 'input-only', pkgVersion: '0.1.0', - manifests: { + manifestsAndRoutingRules: { 'input-only-0.1.0/data_stream/stream1/manifest.yml': Buffer.from( ` title: Custom Logs @@ -532,7 +532,7 @@ describe('parseAndVerifyDataStreams', () => { paths: ['input-only-0.1.0/data_stream/stream1/manifest.yml'], pkgName: 'input-only', pkgVersion: '0.1.0', - manifests: { + manifestsAndRoutingRules: { 'input-only-0.1.0/data_stream/stream1/manifest.yml': Buffer.from( ` title: Custom Logs @@ -558,6 +558,58 @@ describe('parseAndVerifyDataStreams', () => { }, ]); }); + + it('should parse routing rules', async () => { + expect( + parseAndVerifyDataStreams({ + paths: ['input-only-0.1.0/data_stream/stream1/manifest.yml'], + pkgName: 'input-only', + pkgVersion: '0.1.0', + manifestsAndRoutingRules: { + 'input-only-0.1.0/data_stream/stream1/manifest.yml': Buffer.from( + ` + title: Custom Logs + type: logs + dataset: ds + version: 0.1.0`, + 'utf8' + ), + 'input-only-0.1.0/data_stream/stream1/routing_rules.yml': Buffer.from( + ` + - source_dataset: ds + rules: + - target_dataset: ds.test + if: true == true + namespace: "default" + `, + 'utf8' + ), + }, + }) + ).toEqual([ + { + dataset: 'ds', + package: 'input-only', + path: 'stream1', + release: 'ga', + title: 'Custom Logs', + type: 'logs', + elasticsearch: {}, + routing_rules: [ + { + source_dataset: 'ds', + rules: [ + { + target_dataset: 'ds.test', + if: 'true == true', + namespace: 'default', + }, + ], + }, + ], + }, + ]); + }); }); describe('parseAndVerifyStreams', () => { diff --git a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts index 705f1f93ac78b..eb5895a4f769d 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/parse.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/parse.ts @@ -39,6 +39,8 @@ import { unpackBufferEntries } from '.'; const readFileAsync = promisify(readFile); export const MANIFEST_NAME = 'manifest.yml'; +export const DATASTREAM_MANIFEST_NAME = 'manifest.yml'; +export const DATASTREAM_ROUTING_RULES_NAME = 'routing_rules.yml'; const DEFAULT_RELEASE_VALUE = 'ga'; @@ -79,7 +81,7 @@ export const expandDottedEntries = (obj: object) => { }, {} as Record); }; -type ManifestMap = Record; +type AssetsBufferMap = Record; // not sure these are 100% correct but they do the job here // keeping them local until others need them @@ -142,16 +144,21 @@ export async function generatePackageInfoFromArchiveBuffer( archiveBuffer: Buffer, contentType: string ): Promise<{ paths: string[]; packageInfo: ArchivePackage }> { - const manifests: ManifestMap = {}; + const manifestsAndRoutingRules: AssetsBufferMap = {}; const entries = await unpackBufferEntries(archiveBuffer, contentType); const paths: string[] = []; entries.forEach(({ path: bufferPath, buffer }) => { paths.push(bufferPath); - if (bufferPath.endsWith(MANIFEST_NAME) && buffer) manifests[bufferPath] = buffer; + if ( + buffer && + (bufferPath.endsWith(MANIFEST_NAME) || bufferPath.endsWith(DATASTREAM_ROUTING_RULES_NAME)) + ) { + manifestsAndRoutingRules[bufferPath] = buffer; + } }); return { - packageInfo: parseAndVerifyArchive(paths, manifests), + packageInfo: parseAndVerifyArchive(paths, manifestsAndRoutingRules), paths, }; } @@ -164,18 +171,21 @@ export async function _generatePackageInfoFromPaths( paths: string[], topLevelDir: string ): Promise { - const manifests: ManifestMap = {}; + const manifestsAndRoutingRules: AssetsBufferMap = {}; await Promise.all( paths.map(async (filePath) => { - if (filePath.endsWith(MANIFEST_NAME)) manifests[filePath] = await readFileAsync(filePath); + if (filePath.endsWith(MANIFEST_NAME) || filePath.endsWith(DATASTREAM_ROUTING_RULES_NAME)) { + manifestsAndRoutingRules[filePath] = await readFileAsync(filePath); + } }) ); - return parseAndVerifyArchive(paths, manifests, topLevelDir); + + return parseAndVerifyArchive(paths, manifestsAndRoutingRules, topLevelDir); } export function parseAndVerifyArchive( paths: string[], - manifests: ManifestMap, + manifestsAndRoutingRules: AssetsBufferMap, topLevelDirOverride?: string ): ArchivePackage { // The top-level directory must match pkgName-pkgVersion, and no other top-level files or directories may be present @@ -190,7 +200,7 @@ export function parseAndVerifyArchive( // The package must contain a manifest file ... const manifestFile = path.posix.join(toplevelDir, MANIFEST_NAME); - const manifestBuffer = manifests[manifestFile]; + const manifestBuffer = manifestsAndRoutingRules[manifestFile]; if (!paths.includes(manifestFile) || !manifestBuffer) { throw new PackageInvalidArchiveError( `Package at top-level directory ${toplevelDir} must contain a top-level ${MANIFEST_NAME} file.` @@ -239,7 +249,7 @@ export function parseAndVerifyArchive( pkgName: parsed.name, pkgVersion: parsed.version, pkgBasePathOverride: topLevelDirOverride, - manifests, + manifestsAndRoutingRules, }); if (parsedDataStreams.length) { @@ -284,10 +294,10 @@ export function parseAndVerifyDataStreams(opts: { paths: string[]; pkgName: string; pkgVersion: string; - manifests: ManifestMap; + manifestsAndRoutingRules: AssetsBufferMap; pkgBasePathOverride?: string; }): RegistryDataStream[] { - const { paths, pkgName, pkgVersion, manifests, pkgBasePathOverride } = opts; + const { paths, pkgName, pkgVersion, manifestsAndRoutingRules, pkgBasePathOverride } = opts; // A data stream is made up of a subdirectory of name-version/data_stream/, containing a manifest.yml const dataStreamPaths = new Set(); const dataStreams: RegistryDataStream[] = []; @@ -305,8 +315,8 @@ export function parseAndVerifyDataStreams(opts: { dataStreamPaths.forEach((dataStreamPath) => { const fullDataStreamPath = path.posix.join(dataStreamsBasePath, dataStreamPath); - const manifestFile = path.posix.join(fullDataStreamPath, MANIFEST_NAME); - const manifestBuffer = manifests[manifestFile]; + const manifestFile = path.posix.join(fullDataStreamPath, DATASTREAM_MANIFEST_NAME); + const manifestBuffer = manifestsAndRoutingRules[manifestFile]; if (!paths.includes(manifestFile) || !manifestBuffer) { throw new PackageInvalidArchiveError( `No manifest.yml file found for data stream '${dataStreamPath}'` @@ -322,6 +332,20 @@ export function parseAndVerifyDataStreams(opts: { ); } + // Routing rules + const routingRulesFiles = path.posix.join(fullDataStreamPath, DATASTREAM_ROUTING_RULES_NAME); + const routingRulesBuffer = manifestsAndRoutingRules[routingRulesFiles]; + let dataStreamRoutingRules: any; + if (routingRulesBuffer) { + try { + dataStreamRoutingRules = yaml.safeLoad(routingRulesBuffer.toString()); + } catch (error) { + throw new PackageInvalidArchiveError( + `Could not parse package manifest for data stream '${dataStreamPath}': ${error}.` + ); + } + } + const { title: dataStreamTitle, release = DEFAULT_RELEASE_VALUE, @@ -357,6 +381,10 @@ export function parseAndVerifyDataStreams(opts: { elasticsearch: parsedElasticsearchEntry, }; + if (dataStreamRoutingRules) { + dataStreamObject.routing_rules = dataStreamRoutingRules; + } + if (ingestPipeline) { dataStreamObject.ingest_pipeline = ingestPipeline; } diff --git a/x-pack/plugins/fleet/server/services/epm/archive/storage.ts b/x-pack/plugins/fleet/server/services/epm/archive/storage.ts index cbea18b8b8338..6608294c10077 100644 --- a/x-pack/plugins/fleet/server/services/epm/archive/storage.ts +++ b/x-pack/plugins/fleet/server/services/epm/archive/storage.ts @@ -24,7 +24,7 @@ import { appContextService } from '../../app_context'; import { getArchiveEntry, setArchiveEntry, setArchiveFilelist, setPackageInfo } from '.'; import type { ArchiveEntry } from '.'; -import { MANIFEST_NAME, parseAndVerifyArchive } from './parse'; +import { DATASTREAM_ROUTING_RULES_NAME, MANIFEST_NAME, parseAndVerifyArchive } from './parse'; const ONE_BYTE = 1024 * 1024; // could be anything, picked this from https://github.com/elastic/elastic-agent-client/issues/17 @@ -207,7 +207,7 @@ export const getEsPackage = async ( return undefined; } - const manifests: Record = {}; + const manifestsAndRoutingRules: Record = {}; const entries: ArchiveEntry[] = assets.map(packageAssetToArchiveEntry); const paths: string[] = []; entries.forEach(({ path, buffer }) => { @@ -216,12 +216,16 @@ export const getEsPackage = async ( paths.push(path); } paths.push(path); - if (path.endsWith(MANIFEST_NAME) && buffer) manifests[path] = buffer; + if (path.endsWith(MANIFEST_NAME) && buffer) { + manifestsAndRoutingRules[path] = buffer; + } else if (path.endsWith(DATASTREAM_ROUTING_RULES_NAME) && buffer) { + manifestsAndRoutingRules[path] = buffer; + } }); // // Add asset references to cache setArchiveFilelist({ name: pkgName, version: pkgVersion }, paths); - const packageInfo = parseAndVerifyArchive(paths, manifests); + const packageInfo = parseAndVerifyArchive(paths, manifestsAndRoutingRules); setPackageInfo({ name: pkgName, version: pkgVersion, packageInfo }); return { diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.test.ts index fcd60ec51e69e..d43849d216810 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.test.ts @@ -11,7 +11,7 @@ import path from 'path'; import type { RegistryDataStream } from '../../../../types'; import { - addCustomPipelineProcessor, + addCustomPipelineAndLocalRoutingRulesProcessor, getPipelineNameForInstallation, rewriteIngestPipeline, } from './helpers'; @@ -142,9 +142,9 @@ test('getPipelineNameForInstallation gets correct name', () => { ); }); -describe('addCustomPipelineProcessor', () => { +describe('addCustomPipelineAndLocalRoutingRulesProcessor', () => { it('add custom pipeline processor at the end of the pipeline for yaml pipeline', () => { - const pipelineInstall = addCustomPipelineProcessor({ + const pipelineInstall = addCustomPipelineAndLocalRoutingRulesProcessor({ contentForInstallation: ` processors: - set: @@ -170,7 +170,7 @@ processors: }); it('add custom pipeline processor at the end of the pipeline for json pipeline', () => { - const pipelineInstall = addCustomPipelineProcessor({ + const pipelineInstall = addCustomPipelineAndLocalRoutingRulesProcessor({ contentForInstallation: `{ "processors": [ { @@ -190,4 +190,89 @@ processors: `"{\\"processors\\":[{\\"set\\":{\\"field\\":\\"test\\",\\"value\\":\\"toto\\"}},{\\"pipeline\\":{\\"name\\":\\"logs-test@custom\\",\\"ignore_missing_pipeline\\":true}}]}"` ); }); + + describe('with local routing rules', () => { + it('add reroute processor after custom pipeline processor for yaml pipeline', () => { + const pipelineInstall = addCustomPipelineAndLocalRoutingRulesProcessor({ + contentForInstallation: ` +processors: + - set: + field: test + value: toto + `, + extension: 'yml', + nameForInstallation: 'logs-test-1.0.0', + customIngestPipelineNameForInstallation: 'logs-test@custom', + dataStream: { + dataset: 'test', + routing_rules: [ + { + source_dataset: 'test', + rules: [ + { + target_dataset: 'test.reroute', + if: 'true == true', + namespace: 'default', + }, + ], + }, + ], + } as any, + }); + + expect(pipelineInstall.contentForInstallation).toMatchInlineSnapshot(` + "--- + processors: + - set: + field: test + value: toto + - pipeline: + name: logs-test@custom + ignore_missing_pipeline: true + - reroute: + tag: test + dataset: test.reroute + namespace: default + if: true == true + " + `); + }); + + it('add reroute processor after custom pipeline processor for json pipeline', () => { + const pipelineInstall = addCustomPipelineAndLocalRoutingRulesProcessor({ + contentForInstallation: `{ + "processors": [ + { + "set": { + "field": "test", + "value": "toto" + } + } + ] + }`, + extension: 'json', + nameForInstallation: 'logs-test-1.0.0', + customIngestPipelineNameForInstallation: 'logs-test@custom', + dataStream: { + dataset: 'test', + routing_rules: [ + { + source_dataset: 'test', + rules: [ + { + target_dataset: 'test.reroute', + if: 'true == true', + namespace: 'default', + }, + ], + }, + ], + } as any, + }); + + expect(pipelineInstall.contentForInstallation).toMatchInlineSnapshot( + `"{\\"processors\\":[{\\"set\\":{\\"field\\":\\"test\\",\\"value\\":\\"toto\\"}},{\\"pipeline\\":{\\"name\\":\\"logs-test@custom\\",\\"ignore_missing_pipeline\\":true}},{\\"reroute\\":{\\"tag\\":\\"test\\",\\"dataset\\":\\"test.reroute\\",\\"namespace\\":\\"default\\",\\"if\\":\\"true == true\\"}}]}"` + ); + }); + }); }); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.ts index 0ce78b5730ac0..1be2b2b895896 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.ts @@ -69,21 +69,39 @@ function mutatePipelineContentWithNewProcessor(jsonPipelineContent: any, process jsonPipelineContent.processors.push(processor); } -export function addCustomPipelineProcessor(pipeline: PipelineInstall): PipelineInstall { +export function addCustomPipelineAndLocalRoutingRulesProcessor( + pipeline: PipelineInstall +): PipelineInstall { if (!pipeline.customIngestPipelineNameForInstallation) { return pipeline; } + const localRoutingRules = + pipeline.dataStream?.routing_rules?.find( + (rule) => rule.source_dataset === pipeline.dataStream?.dataset + )?.rules ?? []; + const customPipelineProcessor = { pipeline: { name: pipeline.customIngestPipelineNameForInstallation, ignore_missing_pipeline: true, }, }; + const rerouteProcessors = localRoutingRules.map((routingRule) => ({ + reroute: { + tag: pipeline.dataStream?.dataset, + dataset: routingRule.target_dataset, + namespace: routingRule.namespace, + if: routingRule.if, + }, + })); if (pipeline.extension === 'yml') { const parsedPipelineContent = safeLoad(pipeline.contentForInstallation); mutatePipelineContentWithNewProcessor(parsedPipelineContent, customPipelineProcessor); + rerouteProcessors.forEach((processor) => + mutatePipelineContentWithNewProcessor(parsedPipelineContent, processor) + ); return { ...pipeline, contentForInstallation: `---\n${safeDump(parsedPipelineContent)}`, @@ -92,6 +110,9 @@ export function addCustomPipelineProcessor(pipeline: PipelineInstall): PipelineI const parsedPipelineContent = JSON.parse(pipeline.contentForInstallation); mutatePipelineContentWithNewProcessor(parsedPipelineContent, customPipelineProcessor); + rerouteProcessors.forEach((processor) => + mutatePipelineContentWithNewProcessor(parsedPipelineContent, processor) + ); return { ...pipeline, diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts index 5e063e26c6a63..1ae0d8a9d67fa 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts @@ -34,7 +34,7 @@ import { getPipelineNameForInstallation, rewriteIngestPipeline, isTopLevelPipeline, - addCustomPipelineProcessor, + addCustomPipelineAndLocalRoutingRulesProcessor, } from './helpers'; import type { PipelineInstall, RewriteSubstitution } from './types'; @@ -152,12 +152,9 @@ export async function installAllPipelines({ const pipelinePaths = dataStream ? paths.filter((path) => isDataStreamPipeline(path, dataStream.path)) : paths; - const pipelinesInfos: Array<{ - nameForInstallation: string; - customIngestPipelineNameForInstallation?: string; - content: string; - extension: string; - }> = []; + const pipelinesInfos: Array< + Omit & { content: string } + > = []; const substitutions: RewriteSubstitution[] = []; let datastreamPipelineCreated = false; @@ -177,6 +174,7 @@ export async function installAllPipelines({ nameForInstallation, customIngestPipelineNameForInstallation: dataStream && isMainPipeline ? getCustomPipelineNameForDatastream(dataStream) : undefined, + dataStream, content, extension, }); @@ -203,6 +201,7 @@ export async function installAllPipelines({ pipelinesToInstall.push({ nameForInstallation, customIngestPipelineNameForInstallation: getCustomPipelineNameForDatastream(dataStream), + dataStream, contentForInstallation: 'processors: []', extension: 'yml', }); @@ -234,7 +233,7 @@ async function installPipeline({ }); if (shouldAddCustomPipelineProcessor) { - pipelineToInstall = addCustomPipelineProcessor(pipelineToInstall); + pipelineToInstall = addCustomPipelineAndLocalRoutingRulesProcessor(pipelineToInstall); } const esClientParams = { diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/types.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/types.ts index c9b7a68e3d892..329fc744320e1 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/types.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/types.ts @@ -5,11 +5,14 @@ * 2.0. */ +import type { RegistryDataStream } from '../../../../types'; + export interface PipelineInstall { nameForInstallation: string; contentForInstallation: string; customIngestPipelineNameForInstallation?: string; extension: string; + dataStream?: RegistryDataStream; } export interface RewriteSubstitution { diff --git a/x-pack/test/fleet_api_integration/apis/epm/custom_ingest_pipeline.ts b/x-pack/test/fleet_api_integration/apis/epm/custom_ingest_pipeline.ts index 06b5a245cd78c..22490b4bbe31d 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/custom_ingest_pipeline.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/custom_ingest_pipeline.ts @@ -78,7 +78,7 @@ export default function (providerContext: FtrProviderContext) { }); }); - describe('Without custom pipeline', () => { + describe('With custom pipeline', () => { before(() => es.ingest.putPipeline({ id: CUSTOM_PIPELINE, diff --git a/x-pack/test/fleet_api_integration/apis/epm/index.js b/x-pack/test/fleet_api_integration/apis/epm/index.js index 70b655a59424b..2fa0c0c881a59 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/index.js +++ b/x-pack/test/fleet_api_integration/apis/epm/index.js @@ -43,6 +43,7 @@ export default function loadTests({ loadTestFile, getService }) { loadTestFile(require.resolve('./install_hidden_datastreams')); loadTestFile(require.resolve('./bulk_get_assets')); loadTestFile(require.resolve('./install_dynamic_template_metric')); + loadTestFile(require.resolve('./routing_rules')); loadTestFile(require.resolve('./install_runtime_field')); }); } diff --git a/x-pack/test/fleet_api_integration/apis/epm/routing_rules.ts b/x-pack/test/fleet_api_integration/apis/epm/routing_rules.ts new file mode 100644 index 0000000000000..c030913bfbcb6 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/epm/routing_rules.ts @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { setupFleetAndAgents } from '../agents/services'; +import { skipIfNoDockerRegistry } from '../../helpers'; + +const TEST_WRITE_INDEX = 'logs-routing_rules.test-test'; +const TEST_REROUTE_INDEX = 'logs-routing_rules.reroute-test'; + +const ROUTING_RULES_PKG_NAME = 'routing_rules'; +const ROUTING_RULES_PKG_VERSION = '1.0.0'; + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const supertest = getService('supertest'); + const es = getService('es'); + const esArchiver = getService('esArchiver'); + + describe('routing rules for fleet managed datastreams', () => { + skipIfNoDockerRegistry(providerContext); + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server'); + }); + setupFleetAndAgents(providerContext); + + before(async () => { + await supertest + .post(`/api/fleet/epm/packages/${ROUTING_RULES_PKG_NAME}/${ROUTING_RULES_PKG_VERSION}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }) + .expect(200); + }); + after(async () => { + await supertest + .delete(`/api/fleet/epm/packages/${ROUTING_RULES_PKG_NAME}/${ROUTING_RULES_PKG_VERSION}`) + .set('kbn-xsrf', 'xxxx') + .send({ force: true }) + .expect(200); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server'); + }); + + after(async () => { + const res = await es.search({ + index: TEST_REROUTE_INDEX, + ignore_unavailable: true, + }); + + for (const hit of res.hits.hits) { + await es.delete({ + id: hit._id, + index: hit._index, + }); + } + }); + + it('Should write doc correctly and apply the routing rule', async () => { + const res = await es.index({ + index: TEST_WRITE_INDEX, + body: { + '@timestamp': '2020-01-01T09:09:00', + message: 'hello', + data_stream: { + dataset: 'routing_rules.test', + namespace: 'test', + type: 'logs', + }, + }, + }); + + const resWrite = await es.get({ + id: res._id, + index: res._index, + }); + + expect(resWrite._index.match(/logs-routing_rules.reroute-test/)); + }); + }); +} diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/fields/fields.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/fields/fields.yml new file mode 100644 index 0000000000000..86913eaec22a7 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/fields/fields.yml @@ -0,0 +1,18 @@ +- name: data_stream.type + type: constant_keyword + description: > + Data stream type. +- name: data_stream.dataset + type: constant_keyword + description: > + Data stream dataset. +- name: data_stream.namespace + type: constant_keyword + description: > + Data stream namespace. +- name: '@timestamp' + type: date + description: > + Event timestamp. +- name: 'message' + type: text diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/manifest.yml new file mode 100644 index 0000000000000..0ba1541287a2e --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/manifest.yml @@ -0,0 +1,6 @@ +title: Test Dataset +dataset: routing_rules.test +type: logs +elasticsearch: + dynamic_dataset: true + dynamic_namespace: true diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/routing_rules.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/routing_rules.yml new file mode 100644 index 0000000000000..6a90d41bddf73 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/data_stream/test/routing_rules.yml @@ -0,0 +1,9 @@ +# "Local" routing rules are included under this current dataset, not a special case +- source_dataset: routing_rules.test + rules: + # Route error logs to `nginx.error` when they're sourced from an error logfile + - target_dataset: routing_rules.reroute + if: 'true == true' + namespace: + - '{{ data_stream.namespace }}' + - default diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/docs/README.md b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/docs/README.md new file mode 100644 index 0000000000000..131f0fdfde9bb --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/docs/README.md @@ -0,0 +1,3 @@ +# routing rules + +This package has routing rules diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/img/logo.svg b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/img/logo.svg new file mode 100644 index 0000000000000..15b49bcf28aec --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/img/logo.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/manifest.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/manifest.yml new file mode 100644 index 0000000000000..efc9c8d1820c9 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/routing_rules/1.0.0/manifest.yml @@ -0,0 +1,25 @@ +format_version: 2.9.0 +name: routing_rules +title: Package with routing rules +description: This integration package has routing rules. +version: 1.0.0 +categories: [] +# Options are experimental, beta, ga +release: beta +# The package type. The options for now are [integration, solution], more type might be added in the future. +# The default type is integration and will be set if empty. +type: integration +license: basic +owner: + github: elastic/fleet + +requirement: + elasticsearch: + versions: '>7.7.0' + kibana: + versions: '>7.7.0' + +icons: + - src: '/img/logo.svg' + size: '16x16' + type: 'image/svg+xml' From f022456ad89fd5545586b03240ccfb4c4da5aa05 Mon Sep 17 00:00:00 2001 From: "Christiane (Tina) Heiligers" Date: Wed, 12 Jul 2023 10:19:20 -0700 Subject: [PATCH 82/97] [http] Default route access to `internal` (#161672) --- .../src/request.ts | 5 ++--- .../src/router.mock.ts | 2 +- .../src/http_server.test.ts | 16 ++++++++-------- .../core-http-server-internal/src/http_server.ts | 2 +- .../src/lifecycle_handlers.test.ts | 2 +- .../http/core-http-server/src/router/route.ts | 4 +--- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/core/http/core-http-router-server-internal/src/request.ts b/packages/core/http/core-http-router-server-internal/src/request.ts index aa134c21ae95a..8c31635feb8c2 100644 --- a/packages/core/http/core-http-router-server-internal/src/request.ts +++ b/packages/core/http/core-http-router-server-internal/src/request.ts @@ -223,11 +223,10 @@ export class CoreKibanaRequest< options, }; } - /** infer route access from path if not declared */ + /** set route access to internal if not declared */ private getAccess(request: RawRequest): 'internal' | 'public' { return ( - ((request.route?.settings as RouteOptions)?.app as KibanaRouteOptions)?.access ?? - (request.path.startsWith('/internal') ? 'internal' : 'public') + ((request.route?.settings as RouteOptions)?.app as KibanaRouteOptions)?.access ?? 'internal' ); } diff --git a/packages/core/http/core-http-router-server-mocks/src/router.mock.ts b/packages/core/http/core-http-router-server-mocks/src/router.mock.ts index e82a51a14a332..4272cf130b38e 100644 --- a/packages/core/http/core-http-router-server-mocks/src/router.mock.ts +++ b/packages/core/http/core-http-router-server-mocks/src/router.mock.ts @@ -73,7 +73,7 @@ function createKibanaRequestMock

({ routeTags, routeAuthRequired, validation = {}, - kibanaRouteOptions = { xsrfRequired: true, access: 'public' }, + kibanaRouteOptions = { xsrfRequired: true, access: 'internal' }, kibanaRequestState = { requestId: '123', requestUuid: '123e4567-e89b-12d3-a456-426614174000', diff --git a/packages/core/http/core-http-server-internal/src/http_server.test.ts b/packages/core/http/core-http-server-internal/src/http_server.test.ts index 886349e0ea940..675d7e4fffcef 100644 --- a/packages/core/http/core-http-server-internal/src/http_server.test.ts +++ b/packages/core/http/core-http-server-internal/src/http_server.test.ts @@ -836,12 +836,12 @@ test('allows declaring route access to flag a route as public or internal', asyn registerRouter(router); await server.start(); - await supertest(innerServer.listener).get('/with-access').expect(200, { access }); + await supertest(innerServer.listener).get('/with-access').expect(200, { access: 'internal' }); - await supertest(innerServer.listener).get('/without-access').expect(200, { access: 'public' }); + await supertest(innerServer.listener).get('/without-access').expect(200, { access: 'internal' }); }); -test('infers access flag from path if not defined', async () => { +test(`sets access flag to 'internal' if not defined`, async () => { const { registerRouter, server: innerServer } = await server.setup(config); const router = new Router('', logger, enhanceWithContext, routerOptions); @@ -863,13 +863,13 @@ test('infers access flag from path if not defined', async () => { await server.start(); await supertest(innerServer.listener).get('/internal/foo').expect(200, { access: 'internal' }); - await supertest(innerServer.listener).get('/random/foo').expect(200, { access: 'public' }); + await supertest(innerServer.listener).get('/random/foo').expect(200, { access: 'internal' }); await supertest(innerServer.listener) .get('/random/internal/foo') - .expect(200, { access: 'public' }); + .expect(200, { access: 'internal' }); await supertest(innerServer.listener) .get('/api/foo/internal/my-foo') - .expect(200, { access: 'public' }); + .expect(200, { access: 'internal' }); }); test('exposes route details of incoming request to a route handler', async () => { @@ -888,7 +888,7 @@ test('exposes route details of incoming request to a route handler', async () => options: { authRequired: true, xsrfRequired: false, - access: 'public', + access: 'internal', tags: [], timeout: {}, }, @@ -1066,7 +1066,7 @@ test('exposes route details of incoming request to a route handler (POST + paylo options: { authRequired: true, xsrfRequired: true, - access: 'public', + access: 'internal', tags: [], timeout: { payload: 10000, diff --git a/packages/core/http/core-http-server-internal/src/http_server.ts b/packages/core/http/core-http-server-internal/src/http_server.ts index 747c477d1b41d..3ed8a73a38641 100644 --- a/packages/core/http/core-http-server-internal/src/http_server.ts +++ b/packages/core/http/core-http-server-internal/src/http_server.ts @@ -606,7 +606,7 @@ export class HttpServer { const kibanaRouteOptions: KibanaRouteOptions = { xsrfRequired: route.options.xsrfRequired ?? !isSafeMethod(route.method), - access: route.options.access ?? (route.path.startsWith('/internal') ? 'internal' : 'public'), + access: route.options.access ?? 'internal', }; // Log HTTP API target consumer. optionsLogger.debug( diff --git a/packages/core/http/core-http-server-internal/src/lifecycle_handlers.test.ts b/packages/core/http/core-http-server-internal/src/lifecycle_handlers.test.ts index b58fd1b299b06..9e1d0191d0f5e 100644 --- a/packages/core/http/core-http-server-internal/src/lifecycle_handlers.test.ts +++ b/packages/core/http/core-http-server-internal/src/lifecycle_handlers.test.ts @@ -174,7 +174,7 @@ describe('xsrf post-auth handler', () => { path: '/some-path', kibanaRouteOptions: { xsrfRequired: false, - access: 'public', + access: 'internal', }, }); diff --git a/packages/core/http/core-http-server/src/router/route.ts b/packages/core/http/core-http-server/src/router/route.ts index e2b11aec08e1a..349ad2e392453 100644 --- a/packages/core/http/core-http-server/src/router/route.ts +++ b/packages/core/http/core-http-server/src/router/route.ts @@ -126,9 +126,7 @@ export interface RouteConfigOptions { * In the future, may require an incomming request to contain a specified header. * - internal. The route is internal and intended for internal access only. * - * If not declared, infers access from route path: - * - access =`internal` for '/internal' route path prefix - * - access = `public` for everything else + * Defaults to 'internal' If not declared, */ access?: 'public' | 'internal'; From 3ba51e4a31f21c1618edcb45a9daa2737568db10 Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Wed, 12 Jul 2023 15:23:50 -0400 Subject: [PATCH 83/97] [Security Solution][Endpoint] Remove use of Redux from the Endpoint Policy Settings form (#161511) ## Summary - Re-creates all policy settings form components so that the Policy settings are provided as a prop - Adds `mode = view` to the policy form. When in this mode (user has no authz to edit), form will be displayed in view only mode (no more `disabled` form elements) --- .../policy/get_policy_data_for_update.ts | 7 +- .../e2e/mocked_data/policy_details.cy.ts | 88 ++-- .../cypress/screens/policy_details.ts | 11 +- .../hooks/policy/use_fetch_endpoint_policy.ts | 92 ++++ ...use_fetch_endpoint_policy_agent_summary.ts | 37 ++ .../policy/use_update_endpoint_policy.ts | 45 ++ .../policy/models/policy_details_config.ts | 23 - .../selectors/policy_settings_selectors.ts | 8 - .../view/{ => components}/agents_summary.tsx | 0 .../antivirus_registration_form/index.tsx | 82 --- .../attack_surface_reduction_form/index.tsx | 61 --- .../components/config_form/index.stories.tsx | 67 --- .../view/components/events_form/index.tsx | 197 -------- .../management/pages/policy/view/index.ts | 1 - .../endpoint_policy_edit_extension.test.tsx | 10 +- .../endpoint_policy_edit_extension.tsx | 166 ++----- .../pages/policy/view/policy_advanced.tsx | 213 -------- .../pages/policy/view/policy_details.test.tsx | 3 - .../pages/policy/view/policy_details.tsx | 2 +- .../pages/policy/view/policy_details_form.tsx | 131 ----- .../components/policy_form_layout.test.tsx | 470 ------------------ .../components/protection_radio.tsx | 98 ---- .../components/protection_switch.tsx | 134 ----- .../policy_forms/components/radio_buttons.tsx | 86 ---- .../components/supported_version.tsx | 30 -- .../components/user_notification.tsx | 210 -------- .../policy/view/policy_forms/locked_card.tsx | 93 ---- .../policy_forms/protections/behavior.tsx | 74 --- .../view/policy_forms/protections/malware.tsx | 162 ------ .../view/policy_forms/protections/memory.tsx | 74 --- .../protections/popup_options_to_versions.ts | 15 - .../policy_forms/protections/ransomware.tsx | 71 --- .../pages/policy/view/policy_hooks.ts | 30 +- .../components/advanced_section.tsx | 239 +++++++++ .../cards/antivirus_registration_card.tsx | 92 ++++ .../cards/attack_surface_reduction_card.tsx | 95 ++++ .../cards/behaviour_protection_card.tsx | 114 +++++ .../cards/event_collection_card.tsx | 283 +++++++++++ .../cards/linux_event_collection_card.tsx} | 79 +-- .../cards/mac_event_collection_card.tsx} | 30 +- .../cards/malware_protections_card.tsx | 205 ++++++++ .../cards/memory_protection_card.tsx | 116 +++++ .../cards/ransomware_protection_card.tsx | 114 +++++ .../cards/windows_event_collection_card.tsx} | 30 +- .../detect_prevent_protection_level.tsx | 185 +++++++ .../components/notify_user_option.tsx | 291 +++++++++++ .../protection_setting_card_switch.tsx | 140 ++++++ .../components/setting_card.tsx} | 34 +- .../components/setting_locked_card.tsx | 98 ++++ .../index.ts} | 2 +- .../policy/view/policy_settings_form/mocks.ts | 116 +++++ .../policy_settings_form.tsx | 87 ++++ ...ction_notice_supported_endpoint_version.ts | 13 + .../policy/view/policy_settings_form/types.ts | 15 + .../components/policy_form_confirm_update.tsx | 0 .../index.ts} | 4 +- .../policy_settings_layout.tsx} | 192 ++++--- .../pages/policy/view/tabs/policy_tabs.tsx | 11 +- .../management/services/policies/hooks.ts | 1 + .../management/services/policies/ingest.ts | 34 -- .../translations/translations/fr-FR.json | 7 - .../translations/translations/ja-JP.json | 7 - .../translations/translations/zh-CN.json | 7 - .../apps/integrations/policy_details.ts | 149 +++--- .../page_objects/policy_page.ts | 50 +- 65 files changed, 2795 insertions(+), 2836 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/management/hooks/policy/use_fetch_endpoint_policy.ts create mode 100644 x-pack/plugins/security_solution/public/management/hooks/policy/use_fetch_endpoint_policy_agent_summary.ts create mode 100644 x-pack/plugins/security_solution/public/management/hooks/policy/use_update_endpoint_policy.ts delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts rename x-pack/plugins/security_solution/public/management/pages/policy/view/{ => components}/agents_summary.tsx (100%) delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/components/antivirus_registration_form/index.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/components/attack_surface_reduction_form/index.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/components/config_form/index.stories.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/components/events_form/index.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_advanced.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details_form.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_radio.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/radio_buttons.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/supported_version.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/user_notification.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/locked_card.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/behavior.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/memory.tsx delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/popup_options_to_versions.ts delete mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/ransomware.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/advanced_section.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/antivirus_registration_card.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/attack_surface_reduction_card.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/event_collection_card.tsx rename x-pack/plugins/security_solution/public/management/pages/policy/view/{policy_forms/events/linux.tsx => policy_settings_form/components/cards/linux_event_collection_card.tsx} (65%) rename x-pack/plugins/security_solution/public/management/pages/policy/view/{policy_forms/events/mac.tsx => policy_settings_form/components/cards/mac_event_collection_card.tsx} (55%) create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/malware_protections_card.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/memory_protection_card.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/ransomware_protection_card.tsx rename x-pack/plugins/security_solution/public/management/pages/policy/view/{policy_forms/events/windows.tsx => policy_settings_form/components/cards/windows_event_collection_card.tsx} (71%) create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/detect_prevent_protection_level.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/notify_user_option.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx rename x-pack/plugins/security_solution/public/management/pages/policy/view/{components/config_form/index.tsx => policy_settings_form/components/setting_card.tsx} (77%) create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/setting_locked_card.tsx rename x-pack/plugins/security_solution/public/management/pages/policy/view/{policy_forms/components/index.tsx => policy_settings_form/index.ts} (80%) create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/mocks.ts create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/protection_notice_supported_endpoint_version.ts create mode 100644 x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/types.ts rename x-pack/plugins/security_solution/public/management/pages/policy/view/{policy_forms => policy_settings_layout}/components/policy_form_confirm_update.tsx (100%) rename x-pack/plugins/security_solution/public/management/pages/policy/view/{policy_forms/events/index.tsx => policy_settings_layout/index.ts} (68%) rename x-pack/plugins/security_solution/public/management/pages/policy/view/{policy_forms/components/policy_form_layout.tsx => policy_settings_layout/policy_settings_layout.tsx} (51%) diff --git a/x-pack/plugins/security_solution/common/endpoint/service/policy/get_policy_data_for_update.ts b/x-pack/plugins/security_solution/common/endpoint/service/policy/get_policy_data_for_update.ts index 3abf10c9c7147..ef45df503cdc3 100644 --- a/x-pack/plugins/security_solution/common/endpoint/service/policy/get_policy_data_for_update.ts +++ b/x-pack/plugins/security_solution/common/endpoint/service/policy/get_policy_data_for_update.ts @@ -15,9 +15,10 @@ import type { MaybeImmutable, NewPolicyData, PolicyData } from '../../types'; */ export const getPolicyDataForUpdate = (policy: MaybeImmutable): NewPolicyData => { // eslint-disable-next-line @typescript-eslint/naming-convention - const { id, revision, created_by, created_at, updated_by, updated_at, ...newPolicy } = policy; - // cast to `NewPolicyData` (mutable) since we cloned the entire object - const policyDataForUpdate = cloneDeep(newPolicy) as NewPolicyData; + const { id, revision, created_by, created_at, updated_by, updated_at, ...rest } = + policy as PolicyData; + + const policyDataForUpdate: NewPolicyData = cloneDeep(rest); const endpointPolicy = policyDataForUpdate.inputs[0].config.policy.value; // trim custom malware notification string diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/policy_details.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/policy_details.cy.ts index bcc68b642de84..543ce48ffb79d 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/policy_details.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/policy_details.cy.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { getPolicySettingsFormTestSubjects } from '../../../pages/policy/view/policy_settings_form/mocks'; import { ProtectionModes } from '../../../../../common/endpoint/types'; import { PackagePolicyBackupHelper, @@ -30,7 +31,7 @@ describe('Policy Details', () => { beforeEach(() => { login(); - visitPolicyDetailsPage(); + visitPolicyDetailsPage(indexedHostsData.data.integrationPolicies[0].id); }); afterEach(() => { @@ -42,33 +43,43 @@ describe('Policy Details', () => { }); describe('Malware Protection card', () => { + const malwareTestSubj = getPolicySettingsFormTestSubjects().malware; + it('user should be able to see related rules', () => { - cy.getByTestSubj('malwareProtectionsForm').contains('related detection rules').click(); + cy.getByTestSubj(malwareTestSubj.card).contains('related detection rules').click(); cy.url().should('contain', 'app/security/rules/management'); }); it('changing protection level should enable or disable user notification', () => { - cy.getByTestSubj('malwareProtectionSwitch').click(); - cy.getByTestSubj('malwareProtectionSwitch').should('have.attr', 'aria-checked', 'true'); + cy.getByTestSubj(malwareTestSubj.enableDisableSwitch).click(); + cy.getByTestSubj(malwareTestSubj.enableDisableSwitch).should( + 'have.attr', + 'aria-checked', + 'true' + ); // Default: Prevent + Notify user enabled - cy.getByTestSubj('malwareProtectionMode_prevent').find('input').should('be.checked'); - cy.getByTestSubj('malwareUserNotificationCheckbox').should('be.checked'); + cy.getByTestSubj(malwareTestSubj.protectionPreventRadio).find('input').should('be.checked'); + cy.getByTestSubj(malwareTestSubj.notifyUserCheckbox).should('be.checked'); // Changing to Detect -> Notify user disabled - cy.getByTestSubj('malwareProtectionMode_detect').find('label').click(); - cy.getByTestSubj('malwareUserNotificationCheckbox').should('not.be.checked'); + cy.getByTestSubj(malwareTestSubj.protectionDetectRadio).find('label').click(); + cy.getByTestSubj(malwareTestSubj.notifyUserCheckbox).should('not.be.checked'); // Changing back to Prevent -> Notify user enabled - cy.getByTestSubj('malwareProtectionMode_prevent').find('label').click(); - cy.getByTestSubj('malwareUserNotificationCheckbox').should('be.checked'); + cy.getByTestSubj(malwareTestSubj.protectionPreventRadio).find('label').click(); + cy.getByTestSubj(malwareTestSubj.notifyUserCheckbox).should('be.checked'); }); it('disabling protection should disable notification in yaml for every OS', () => { // Enable malware protection and user notification - cy.getByTestSubj('malwareProtectionSwitch').click(); - cy.getByTestSubj('malwareProtectionSwitch').should('have.attr', 'aria-checked', 'true'); + cy.getByTestSubj(malwareTestSubj.enableDisableSwitch).click(); + cy.getByTestSubj(malwareTestSubj.enableDisableSwitch).should( + 'have.attr', + 'aria-checked', + 'true' + ); savePolicyForm(); yieldPolicyConfig().then((policyConfig) => { @@ -78,8 +89,12 @@ describe('Policy Details', () => { }); // disable malware protection - cy.getByTestSubj('malwareProtectionSwitch').click(); - cy.getByTestSubj('malwareProtectionSwitch').should('have.attr', 'aria-checked', 'false'); + cy.getByTestSubj(malwareTestSubj.enableDisableSwitch).click(); + cy.getByTestSubj(malwareTestSubj.enableDisableSwitch).should( + 'have.attr', + 'aria-checked', + 'false' + ); savePolicyForm(); yieldPolicyConfig().then((policyConfig) => { @@ -96,11 +111,12 @@ describe('Policy Details', () => { expect(policyConfig.windows.malware.mode).to.equal(ProtectionModes.off); }); - cy.getByTestSubj('malwareProtectionsForm').should('contain.text', 'Linux'); - cy.getByTestSubj('malwareProtectionsForm').should('contain.text', 'Windows'); - cy.getByTestSubj('malwareProtectionsForm').should('contain.text', 'Mac'); + cy.getByTestSubj(malwareTestSubj.osValuesContainer).should( + 'contain.text', + 'Windows, Mac, Linux' + ); - cy.getByTestSubj('malwareProtectionSwitch').click(); + cy.getByTestSubj(malwareTestSubj.enableDisableSwitch).click(); savePolicyForm(); yieldPolicyConfig().then((policyConfig) => { @@ -112,40 +128,50 @@ describe('Policy Details', () => { }); describe('Ransomware Protection card', () => { + const ransomwareTestSubj = getPolicySettingsFormTestSubjects().ransomware; + it('user should be able to see related rules', () => { - cy.getByTestSubj('ransomwareProtectionsForm').contains('related detection rules').click(); + cy.getByTestSubj(ransomwareTestSubj.card).contains('related detection rules').click(); cy.url().should('contain', 'app/security/rules/management'); }); it('changing protection level should enable or disable user notification', () => { - cy.getByTestSubj('ransomwareProtectionSwitch').click(); - cy.getByTestSubj('ransomwareProtectionSwitch').should('have.attr', 'aria-checked', 'true'); + cy.getByTestSubj(ransomwareTestSubj.enableDisableSwitch).click(); + cy.getByTestSubj(ransomwareTestSubj.enableDisableSwitch).should( + 'have.attr', + 'aria-checked', + 'true' + ); // Default: Prevent + Notify user enabled - cy.getByTestSubj('ransomwareProtectionMode_prevent').find('input').should('be.checked'); - cy.getByTestSubj('ransomwareUserNotificationCheckbox').should('be.checked'); + cy.getByTestSubj(ransomwareTestSubj.protectionPreventRadio) + .find('input') + .should('be.checked'); + cy.getByTestSubj(ransomwareTestSubj.notifyUserCheckbox).should('be.checked'); // Changing to Detect -> Notify user disabled - cy.getByTestSubj('ransomwareProtectionMode_detect').find('label').click(); - cy.getByTestSubj('ransomwareUserNotificationCheckbox').should('not.be.checked'); + cy.getByTestSubj(ransomwareTestSubj.protectionDetectRadio).find('label').click(); + cy.getByTestSubj(ransomwareTestSubj.notifyUserCheckbox).should('not.be.checked'); // Changing back to Prevent -> Notify user enabled - cy.getByTestSubj('ransomwareProtectionMode_prevent').find('label').click(); - cy.getByTestSubj('ransomwareUserNotificationCheckbox').should('be.checked'); + cy.getByTestSubj(ransomwareTestSubj.protectionPreventRadio).find('label').click(); + cy.getByTestSubj(ransomwareTestSubj.notifyUserCheckbox).should('be.checked'); }); }); describe('Advanced settings', () => { + const testSubjects = getPolicySettingsFormTestSubjects().advancedSection; + it('should show empty text inputs except for some settings', () => { const settingsWithDefaultValues = [ 'mac.advanced.capture_env_vars', 'linux.advanced.capture_env_vars', ]; - cy.getByTestSubj('advancedPolicyButton').click(); + cy.getByTestSubj(testSubjects.showHideButton).click(); - cy.getByTestSubj('advancedPolicyPanel') + cy.getByTestSubj(testSubjects.settingsContainer) .children() .each(($child) => { const settingName = $child.find('label').text(); @@ -167,8 +193,8 @@ describe('Policy Details', () => { }); // Set agent.connection_delay entry for every OS - cy.getByTestSubj('advancedPolicyButton').click(); - cy.getByTestSubj('advancedPolicyPanel') + cy.getByTestSubj(testSubjects.showHideButton).click(); + cy.getByTestSubj(testSubjects.settingsContainer) .children() .each(($child) => { const settingName = $child.find('label').text(); diff --git a/x-pack/plugins/security_solution/public/management/cypress/screens/policy_details.ts b/x-pack/plugins/security_solution/public/management/cypress/screens/policy_details.ts index de4649d3bab4c..30b0b392ff456 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/screens/policy_details.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/screens/policy_details.ts @@ -18,10 +18,13 @@ import type { PolicyConfig } from '../../../../common/endpoint/types'; import { request, loadPage } from '../tasks/common'; import { expectAndCloseSuccessToast } from '../tasks/toasts'; -export const visitPolicyDetailsPage = () => { - loadPage(APP_POLICIES_PATH); - - cy.getByTestSubj('policyNameCellLink').eq(0).click({ force: true }); +export const visitPolicyDetailsPage = (policyId?: string) => { + if (policyId) { + loadPage(`${APP_POLICIES_PATH}/${policyId}`); + } else { + cy.visit(APP_POLICIES_PATH); + cy.getByTestSubj('policyNameCellLink').eq(0).click({ force: true }); + } cy.getByTestSubj('policyDetailsPage').should('exist'); cy.get('#settings').should('exist'); // waiting for Policy Settings tab }; diff --git a/x-pack/plugins/security_solution/public/management/hooks/policy/use_fetch_endpoint_policy.ts b/x-pack/plugins/security_solution/public/management/hooks/policy/use_fetch_endpoint_policy.ts new file mode 100644 index 0000000000000..78cf98c6b48bd --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/hooks/policy/use_fetch_endpoint_policy.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; +import type { IHttpFetchError } from '@kbn/core-http-browser'; +import { useQuery } from '@tanstack/react-query'; +import { packagePolicyRouteService } from '@kbn/fleet-plugin/common'; +import { + DefaultPolicyNotificationMessage, + DefaultPolicyRuleNotificationMessage, +} from '../../../../common/endpoint/models/policy_config'; +import type { GetPolicyResponse } from '../../pages/policy/types'; +import { useHttp } from '../../../common/lib/kibana'; +import type { PolicyData, PolicyConfig } from '../../../../common/endpoint/types'; +import type { ManifestSchema } from '../../../../common/endpoint/schema/manifest'; + +interface ApiDataResponse { + /** Data return from the Fleet API. Its the full integration policy (package policy) */ + item: PolicyData; + /** Endpoint policy settings from the data retrieved from fleet */ + settings: PolicyConfig; + /** Endpoint policy manifest info from the data retrieved from fleet */ + artifactManifest: ManifestSchema; +} + +type UseFetchEndpointPolicyResponse = UseQueryResult; + +/** + * Retrieve a single endpoint integration policy (details) + * @param policyId + * @param options + */ +export const useFetchEndpointPolicy = ( + policyId: string, + options: UseQueryOptions = {} +): UseFetchEndpointPolicyResponse => { + const http = useHttp(); + + return useQuery({ + queryKey: ['get-policy-details', policyId], + ...options, + queryFn: async () => { + const apiResponse = await http.get( + packagePolicyRouteService.getInfoPath(policyId) + ); + + applyDefaultsToPolicyIfNeeded(apiResponse.item); + + return { + item: apiResponse.item, + settings: apiResponse.item.inputs[0].config.policy.value, + artifactManifest: apiResponse.item.inputs[0].config.artifact_manifest.value, + }; + }, + }); +}; + +const applyDefaultsToPolicyIfNeeded = (policyItem: PolicyData): void => { + const settings = policyItem.inputs[0].config.policy.value; + + // sets default user notification message if policy config message is empty + if (settings.windows.popup.malware.message === '') { + settings.windows.popup.malware.message = DefaultPolicyNotificationMessage; + settings.mac.popup.malware.message = DefaultPolicyNotificationMessage; + settings.linux.popup.malware.message = DefaultPolicyNotificationMessage; + } + if (settings.windows.popup.ransomware.message === '') { + settings.windows.popup.ransomware.message = DefaultPolicyNotificationMessage; + } + if (settings.windows.popup.memory_protection.message === '') { + settings.windows.popup.memory_protection.message = DefaultPolicyRuleNotificationMessage; + } + if (settings.mac.popup.memory_protection.message === '') { + settings.mac.popup.memory_protection.message = DefaultPolicyRuleNotificationMessage; + } + if (settings.linux.popup.memory_protection.message === '') { + settings.linux.popup.memory_protection.message = DefaultPolicyRuleNotificationMessage; + } + if (settings.windows.popup.behavior_protection.message === '') { + settings.windows.popup.behavior_protection.message = DefaultPolicyRuleNotificationMessage; + } + if (settings.mac.popup.behavior_protection.message === '') { + settings.mac.popup.behavior_protection.message = DefaultPolicyRuleNotificationMessage; + } + if (settings.linux.popup.behavior_protection.message === '') { + settings.linux.popup.behavior_protection.message = DefaultPolicyRuleNotificationMessage; + } +}; diff --git a/x-pack/plugins/security_solution/public/management/hooks/policy/use_fetch_endpoint_policy_agent_summary.ts b/x-pack/plugins/security_solution/public/management/hooks/policy/use_fetch_endpoint_policy_agent_summary.ts new file mode 100644 index 0000000000000..929665ee1a290 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/hooks/policy/use_fetch_endpoint_policy_agent_summary.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; +import type { IHttpFetchError } from '@kbn/core-http-browser'; +import type { GetAgentStatusResponse } from '@kbn/fleet-plugin/common'; +import { useQuery } from '@tanstack/react-query'; +import { agentRouteService } from '@kbn/fleet-plugin/common'; +import { useHttp } from '../../../common/lib/kibana'; + +type EndpointPolicyAgentSummary = GetAgentStatusResponse['results']; + +export const useFetchAgentByAgentPolicySummary = ( + /** + * The Fleet Agent Policy ID (NOT the endpoint policy id) + */ + agentPolicyId: string, + options: UseQueryOptions = {} +): UseQueryResult => { + const http = useHttp(); + + return useQuery({ + queryKey: ['get-policy-agent-summary', agentPolicyId], + ...options, + queryFn: async () => { + return ( + await http.get(agentRouteService.getStatusPath(), { + query: { policyId: agentPolicyId }, + }) + ).results; + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/management/hooks/policy/use_update_endpoint_policy.ts b/x-pack/plugins/security_solution/public/management/hooks/policy/use_update_endpoint_policy.ts new file mode 100644 index 0000000000000..a81ca3cb4f30d --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/hooks/policy/use_update_endpoint_policy.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UseMutationOptions, UseMutationResult } from '@tanstack/react-query'; +import type { IHttpFetchError } from '@kbn/core-http-browser'; +import { useMutation } from '@tanstack/react-query'; +import { packagePolicyRouteService } from '@kbn/fleet-plugin/common'; +import { getPolicyDataForUpdate } from '../../../../common/endpoint/service/policy'; +import { useHttp } from '../../../common/lib/kibana'; +import type { PolicyData } from '../../../../common/endpoint/types'; +import type { UpdatePolicyResponse } from '../../pages/policy/types'; + +interface UpdateParams { + policy: PolicyData; +} + +type UseUpdateEndpointPolicyOptions = UseMutationOptions< + UpdatePolicyResponse, + IHttpFetchError, + UpdateParams +>; + +type UseUpdateEndpointPolicyResult = UseMutationResult< + UpdatePolicyResponse, + IHttpFetchError, + UpdateParams +>; + +export const useUpdateEndpointPolicy = ( + options?: UseUpdateEndpointPolicyOptions +): UseUpdateEndpointPolicyResult => { + const http = useHttp(); + + return useMutation(({ policy }) => { + const update = getPolicyDataForUpdate(policy); + + return http.put(packagePolicyRouteService.getUpdatePath(policy.id), { + body: JSON.stringify(update), + }); + }, options); +}; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts b/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts deleted file mode 100644 index e4bf68d337bbf..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/models/policy_details_config.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { cloneDeep } from 'lodash'; -import type { UIPolicyConfig } from '../../../../../common/endpoint/types'; - -/** - * Returns cloned `configuration` with `value` set by the `keyPath`. - */ -export const setIn = - (a: UIPolicyConfig) => - (key: Key) => - (subKey: SubKey) => - (leafKey: LeafKey) => - (v: V): UIPolicyConfig => { - const c = cloneDeep(a); - c[key][subKey][leafKey] = v; - return c; - }; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors/policy_settings_selectors.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors/policy_settings_selectors.ts index 97d6886a49d37..5eac0615cc090 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors/policy_settings_selectors.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/selectors/policy_settings_selectors.ts @@ -186,14 +186,6 @@ export const policyConfig: (s: PolicyDetailsState) => UIPolicyConfig = createSel } ); -export const isAntivirusRegistrationEnabled = createSelector(policyConfig, (uiPolicyConfig) => { - return uiPolicyConfig.windows.antivirus_registration.enabled; -}); - -export const isCredentialHardeningEnabled = createSelector(policyConfig, (uiPolicyConfig) => { - return uiPolicyConfig.windows.attack_surface_reduction.credential_hardening.enabled; -}); - /** is there an api call in flight */ export const isLoading = (state: PolicyDetailsState) => state.isLoading; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/agents_summary.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/components/agents_summary.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/agents_summary.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/components/agents_summary.tsx diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/antivirus_registration_form/index.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/components/antivirus_registration_form/index.tsx deleted file mode 100644 index 7d28619e17e6e..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/antivirus_registration_form/index.tsx +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useCallback } from 'react'; -import { useDispatch } from 'react-redux'; -import { i18n } from '@kbn/i18n'; -import { EuiSpacer, EuiSwitch, EuiText } from '@elastic/eui'; - -import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { isAntivirusRegistrationEnabled } from '../../../store/policy_details/selectors'; -import { useShowEditableFormFields, usePolicyDetailsSelector } from '../../policy_hooks'; -import { ConfigForm } from '../config_form'; - -const TRANSLATIONS: Readonly<{ [K in 'title' | 'description' | 'label']: string }> = { - title: i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.type', - { - defaultMessage: 'Register as antivirus', - } - ), - description: i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.explanation', - { - defaultMessage: - 'Toggle on to register Elastic as an official Antivirus solution for Windows OS. ' + - 'This will also disable Windows Defender.', - } - ), - label: i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.toggle', - { - defaultMessage: 'Register as antivirus', - } - ), -}; - -export const AntivirusRegistrationForm = memo(() => { - const antivirusRegistrationEnabled = usePolicyDetailsSelector(isAntivirusRegistrationEnabled); - const dispatch = useDispatch(); - const showEditableFormFields = useShowEditableFormFields(); - - const handleSwitchChange = useCallback( - (event) => - dispatch({ - type: 'userChangedAntivirusRegistration', - payload: { - enabled: event.target.checked, - }, - }), - [dispatch] - ); - - return ( - - {TRANSLATIONS.description} - - - - ); -}); - -AntivirusRegistrationForm.displayName = 'AntivirusRegistrationForm'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/attack_surface_reduction_form/index.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/components/attack_surface_reduction_form/index.tsx deleted file mode 100644 index 235fef2aeee8d..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/attack_surface_reduction_form/index.tsx +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo, useCallback } from 'react'; -import { useDispatch } from 'react-redux'; -import { i18n } from '@kbn/i18n'; -import { EuiSwitch } from '@elastic/eui'; - -import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { isCredentialHardeningEnabled } from '../../../store/policy_details/selectors'; -import { useShowEditableFormFields, usePolicyDetailsSelector } from '../../policy_hooks'; -import { ConfigForm } from '../config_form'; - -const TRANSLATIONS: Readonly<{ [K in 'title' | 'label']: string }> = { - title: i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.attackSurfaceReduction.type', - { - defaultMessage: 'Attack surface reduction', - } - ), - label: i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.credentialHardening.toggle', - { - defaultMessage: 'Credential hardening', - } - ), -}; - -export const AttackSurfaceReductionForm = memo(() => { - const credentialHardeningEnabled = usePolicyDetailsSelector(isCredentialHardeningEnabled); - const dispatch = useDispatch(); - const showEditableFormFields = useShowEditableFormFields(); - - const handleSwitchChange = useCallback( - (event) => - dispatch({ - type: 'userChangedCredentialHardening', - payload: { - enabled: event.target.checked, - }, - }), - [dispatch] - ); - - return ( - - - - ); -}); - -AttackSurfaceReductionForm.displayName = 'AttackSurfaceReductionForm'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/config_form/index.stories.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/components/config_form/index.stories.tsx deleted file mode 100644 index 79e32cf2e3672..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/config_form/index.stories.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { ThemeProvider } from 'styled-components'; -import { addDecorator, storiesOf } from '@storybook/react'; -import { euiLightVars } from '@kbn/ui-theme'; -import { EuiCheckbox, EuiSpacer, EuiSwitch, EuiText } from '@elastic/eui'; - -import { OperatingSystem } from '@kbn/securitysolution-utils'; - -import { ConfigForm } from '.'; - -addDecorator((storyFn) => ( - ({ eui: euiLightVars, darkMode: false })}>{storyFn()} -)); - -storiesOf('PolicyDetails/ConfigForm', module) - .add('One OS', () => { - return ( - - {'Some content'} - - ); - }) - .add('Multiple OSs', () => { - return ( - - {'Some content'} - - ); - }) - .add('Complex content', () => { - return ( - - - {'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore ' + - 'et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut ' + - 'aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum ' + - 'dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia ' + - 'deserunt mollit anim id est laborum.'} - - - {}} /> - - {}} /> - {}} /> - {}} /> - - ); - }) - .add('Right corner content', () => { - const toggle = {}} />; - - return ( - - {'Some content'} - - ); - }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/events_form/index.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/components/events_form/index.tsx deleted file mode 100644 index a3a0f8c325b0e..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/events_form/index.tsx +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useContext, useCallback } from 'react'; -import { i18n } from '@kbn/i18n'; -import { - EuiCheckbox, - EuiSpacer, - EuiText, - htmlIdGenerator, - EuiIconTip, - EuiBetaBadge, - EuiFlexItem, - EuiFlexGroup, -} from '@elastic/eui'; -import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { ThemeContext } from 'styled-components'; -import type { - PolicyOperatingSystem, - UIPolicyConfig, -} from '../../../../../../../common/endpoint/types'; -import { useShowEditableFormFields, usePolicyDetailsSelector } from '../../policy_hooks'; -import { policyConfig } from '../../../store/policy_details/selectors'; -import { ConfigForm, ConfigFormHeading } from '../config_form'; - -const OPERATING_SYSTEM_TO_TEST_SUBJ: { [K in OperatingSystem]: string } = { - [OperatingSystem.WINDOWS]: 'Windows', - [OperatingSystem.LINUX]: 'Linux', - [OperatingSystem.MAC]: 'Mac', -}; - -interface OperatingSystemToOsMap { - [OperatingSystem.WINDOWS]: PolicyOperatingSystem.windows; - [OperatingSystem.LINUX]: PolicyOperatingSystem.linux; - [OperatingSystem.MAC]: PolicyOperatingSystem.mac; -} - -export type ProtectionField = - keyof UIPolicyConfig[OperatingSystemToOsMap[T]]['events']; - -export type EventFormSelection = { [K in ProtectionField]: boolean }; - -export interface EventFormOption { - name: string; - protectionField: ProtectionField; -} - -export interface SupplementalEventFormOption { - title?: string; - description?: string; - name: string; - protectionField: ProtectionField; - tooltipText?: string; - beta?: boolean; - indented?: boolean; - isDisabled?(policyConfig: UIPolicyConfig): boolean; -} - -export interface EventsFormProps { - os: T; - options: ReadonlyArray>; - selection: EventFormSelection; - onValueSelection: (value: ProtectionField, selected: boolean) => void; - supplementalOptions?: ReadonlyArray>; -} - -const InnerEventsForm = ({ - os, - options, - selection, - onValueSelection, - supplementalOptions, -}: EventsFormProps) => { - const showEditableFormFields = useShowEditableFormFields(); - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const theme = useContext(ThemeContext); - const countSelected = useCallback(() => { - const supplementalSelectionFields: string[] = supplementalOptions - ? supplementalOptions.map((value) => value.protectionField as string) - : []; - return Object.entries(selection).filter(([key, value]) => - !supplementalSelectionFields.includes(key) ? value : false - ).length; - }, [selection, supplementalOptions]); - - return ( - - {i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.eventCollectionsEnabled', - { - defaultMessage: '{selected} / {total} event collections enabled', - values: { - selected: countSelected(), - total: options.length, - }, - } - )} - - } - > - - {i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.eventingEvents', { - defaultMessage: 'Events', - })} - - - {options.map(({ name, protectionField }) => { - return ( - onValueSelection(protectionField, event.target.checked)} - disabled={!showEditableFormFields} - /> - ); - })} - {supplementalOptions && - supplementalOptions.map( - ({ - title, - description, - name, - protectionField, - tooltipText, - beta, - indented, - isDisabled, - }) => { - return ( -

- {title && ( - <> - - {title} - - )} - {description && ( - <> - - - {description} - - - )} - - - - onValueSelection(protectionField, event.target.checked)} - disabled={ - !showEditableFormFields || - (isDisabled ? isDisabled(policyDetailsConfig) : false) - } - /> - - {tooltipText && ( - - - - )} - {beta && ( - - - - )} - -
- ); - } - )} - - ); -}; - -InnerEventsForm.displayName = 'EventsForm'; - -export const EventsForm = React.memo(InnerEventsForm) as typeof InnerEventsForm; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/index.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/index.ts index 540484a710913..d8beeec8b9d60 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/index.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/index.ts @@ -7,4 +7,3 @@ export * from './policy_list'; export * from './policy_details'; -export * from './policy_advanced'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension/endpoint_policy_edit_extension.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension/endpoint_policy_edit_extension.test.tsx index 71bad39304740..ab6c61fef54a2 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension/endpoint_policy_edit_extension.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension/endpoint_policy_edit_extension.test.tsx @@ -14,6 +14,8 @@ import type { AppContextTestRender } from '../../../../../../common/mock/endpoin import { EndpointPolicyEditExtension } from './endpoint_policy_edit_extension'; import { createFleetContextRendererMock } from '../mocks'; import { getUserPrivilegesMockDefaultValue } from '../../../../../../common/components/user_privileges/__mocks__'; +import { FleetPackagePolicyGenerator } from '../../../../../../../common/endpoint/data_generators/fleet_package_policy_generator'; +import { getPolicyDataForUpdate } from '../../../../../../../common/endpoint/service/policy'; jest.mock('../../../../../../common/components/user_privileges'); const useUserPrivilegesMock = useUserPrivileges as jest.Mock; @@ -29,12 +31,16 @@ describe('When displaying the EndpointPolicyEditExtension fleet UI extension', ( beforeEach(() => { const mockedTestContext = createFleetContextRendererMock(); + const policy = new FleetPackagePolicyGenerator('seed').generateEndpointPackagePolicy({ + id: 'someid', + }); + const newPolicy = getPolicyDataForUpdate(policy); render = () => mockedTestContext.render( ); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension/endpoint_policy_edit_extension.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension/endpoint_policy_edit_extension.tsx index a9037ef6c3bb2..fab55babae419 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension/endpoint_policy_edit_extension.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_edit_extension/endpoint_policy_edit_extension.tsx @@ -5,136 +5,68 @@ * 2.0. */ -import React, { memo, useEffect, useState } from 'react'; -import { EuiCallOut, EuiLoadingSpinner, EuiSpacer, EuiText } from '@elastic/eui'; +import React, { memo, useCallback } from 'react'; +import { EuiSpacer, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useDispatch } from 'react-redux'; -import type { - PackagePolicyEditExtensionComponentProps, - NewPackagePolicy, -} from '@kbn/fleet-plugin/public'; +import type { PackagePolicyEditExtensionComponentProps } from '@kbn/fleet-plugin/public'; +import { cloneDeep } from 'lodash'; +import { useUserPrivileges } from '../../../../../../common/components/user_privileges'; +import type { PolicySettingsFormProps } from '../../policy_settings_form/policy_settings_form'; +import type { NewPolicyData } from '../../../../../../../common/endpoint/types'; import { EndpointPolicyArtifactCards } from './components/endpoint_policy_artifact_cards'; -import { getPolicyDetailPath } from '../../../../../common/routing'; -import { PolicyDetailsForm } from '../../policy_details_form'; -import type { AppAction } from '../../../../../../common/store/actions'; -import { usePolicyDetailsSelector } from '../../policy_hooks'; -import { - apiError, - policyDetails, - policyDetailsForUpdate, -} from '../../../store/policy_details/selectors'; +import { PolicySettingsForm } from '../../policy_settings_form'; /** * Exports Endpoint-specific package policy instructions * for use in the Ingest app create / edit package policy */ export const EndpointPolicyEditExtension = memo( - ({ policy, onChange }) => { - return ( - <> - - - - ); - } -); -EndpointPolicyEditExtension.displayName = 'EndpointPolicyEditExtension'; + ({ policy, onChange, newPolicy: _newPolicy }) => { + const policyUpdates = _newPolicy as NewPolicyData; + const endpointPolicySettings = policyUpdates.inputs[0].config.policy.value; + const { canAccessFleet } = useUserPrivileges().endpointPrivileges; -const WrappedPolicyDetailsForm = memo<{ - policyId: string; - onChange: PackagePolicyEditExtensionComponentProps['onChange']; -}>(({ policyId, onChange }) => { - const dispatch = useDispatch<(a: AppAction) => void>(); - const updatedPolicy = usePolicyDetailsSelector(policyDetailsForUpdate); - const endpointPolicyDetails = usePolicyDetailsSelector(policyDetails); - const endpointDetailsLoadingError = usePolicyDetailsSelector(apiError); - const [, setLastUpdatedPolicy] = useState(updatedPolicy); + const endpointPolicySettingsOnChangeHandler: PolicySettingsFormProps['onChange'] = useCallback( + ({ isValid, updatedPolicy }) => { + const newPolicyInputs = cloneDeep(policyUpdates.inputs); + newPolicyInputs[0].config.policy.value = updatedPolicy; - // When the form is initially displayed, trigger the Redux middleware which is based on - // the location information stored via the `userChangedUrl` action. - useEffect(() => { - dispatch({ - type: 'userChangedUrl', - payload: { - hash: '', - pathname: getPolicyDetailPath(policyId, ''), - search: '', + onChange({ + isValid, + updatedPolicy: { inputs: newPolicyInputs }, + }); }, - }); - - // When form is unloaded, reset the redux store - return () => { - dispatch({ - type: 'userChangedUrl', - payload: { - hash: '', - pathname: '/', - search: '', - }, - }); - }; - }, [dispatch, policyId]); + [onChange, policyUpdates.inputs] + ); - useEffect(() => { - // Currently, the `onChange` callback provided by the fleet UI extension is regenerated every - // time the policy data is updated, which means this will go into a continuous loop if we don't - // actually check to see if an update should be reported back to fleet - setLastUpdatedPolicy((prevState) => { - if (prevState === updatedPolicy) { - return prevState; - } + return ( + <> + +
+ - if (updatedPolicy) { - onChange({ - isValid: true, - // send up only the updated policy data which is stored in the `inputs` section. - // All other attributes (like name, id) are updated from the Fleet form, so we want to - // ensure we don't override it. - updatedPolicy: { - // Casting is needed due to the use of `Immutable<>` in our store data - inputs: updatedPolicy.inputs as unknown as NewPackagePolicy['inputs'], - }, - }); - } +
+ +
+ +
+
- return updatedPolicy; - }); - }, [onChange, updatedPolicy]); + - return ( -
- -
- -
- -
-
- - {endpointDetailsLoadingError ? ( - - } - iconType="warning" - color="warning" - data-test-subj="endpiontPolicySettingsLoadingError" - > - {endpointDetailsLoadingError.message} - - ) : !endpointPolicyDetails ? ( - - ) : ( - - )} -
-
- ); -}); -WrappedPolicyDetailsForm.displayName = 'WrappedPolicyDetailsForm'; +
+
+ + ); + } +); +EndpointPolicyEditExtension.displayName = 'EndpointPolicyEditExtension'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_advanced.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_advanced.tsx deleted file mode 100644 index 35141c4cf6d8b..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_advanced.tsx +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback } from 'react'; -import { useDispatch } from 'react-redux'; -import { - EuiCallOut, - EuiFieldText, - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiIconTip, - EuiPanel, - EuiSpacer, - EuiText, -} from '@elastic/eui'; -import { cloneDeep } from 'lodash'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; -import { policyConfig } from '../store/policy_details/selectors'; -import { useShowEditableFormFields, usePolicyDetailsSelector } from './policy_hooks'; -import { AdvancedPolicySchema } from '../models/advanced_policy_schema'; - -function setValue(obj: Record, value: string, path: string[]) { - let newPolicyConfig = obj; - - // First set the value. - for (let i = 0; i < path.length - 1; i++) { - if (!newPolicyConfig[path[i]]) { - newPolicyConfig[path[i]] = {} as Record; - } - newPolicyConfig = newPolicyConfig[path[i]] as Record; - } - newPolicyConfig[path[path.length - 1]] = value; - - // Then, if the user is deleting the value, we need to ensure we clean up the config. - // We delete any sections that are empty, whether that be an empty string, empty object, or undefined. - if (value === '' || value === undefined) { - newPolicyConfig = obj; - for (let k = path.length; k >= 0; k--) { - const nextPath = path.slice(0, k); - for (let i = 0; i < nextPath.length - 1; i++) { - // Traverse and find the next section - newPolicyConfig = newPolicyConfig[nextPath[i]] as Record; - } - if ( - newPolicyConfig[nextPath[nextPath.length - 1]] === undefined || - newPolicyConfig[nextPath[nextPath.length - 1]] === '' || - Object.keys(newPolicyConfig[nextPath[nextPath.length - 1]] as object).length === 0 - ) { - // If we're looking at the `advanced` field, we leave it undefined as opposed to deleting it. - // This is because the UI looks for this field to begin rendering. - if (nextPath[nextPath.length - 1] === 'advanced') { - newPolicyConfig[nextPath[nextPath.length - 1]] = undefined; - // In all other cases, if field is empty, we'll delete it to clean up. - } else { - delete newPolicyConfig[nextPath[nextPath.length - 1]]; - } - newPolicyConfig = obj; - } else { - break; // We are looking at a non-empty section, so we can terminate. - } - } - } -} - -function getValue(obj: Record, path: string[]) { - let currentPolicyConfig = obj; - - for (let i = 0; i < path.length - 1; i++) { - if (currentPolicyConfig[path[i]]) { - currentPolicyConfig = currentPolicyConfig[path[i]] as Record; - } else { - return undefined; - } - } - return currentPolicyConfig[path[path.length - 1]]; -} -const calloutTitle = i18n.translate( - 'xpack.securitySolution.endpoint.policy.advanced.calloutTitle', - { - defaultMessage: 'Proceed with caution!', - } -); -const warningMessage = i18n.translate( - 'xpack.securitySolution.endpoint.policy.advanced.warningMessage', - { - defaultMessage: `This section contains policy values that support advanced use cases. If not configured - properly, these values can cause unpredictable behavior. Please consult documentation - carefully or contact support before editing these values.`, - } -); - -export const AdvancedPolicyForms = React.memo(({ isPlatinumPlus }: { isPlatinumPlus: boolean }) => { - return ( - <> - -

{warningMessage}

-
- - -

- -

-
- - {AdvancedPolicySchema.map((advancedField, index) => { - const configPath = advancedField.key.split('.'); - const failsPlatinumLicenseCheck = !isPlatinumPlus && advancedField.license === 'platinum'; - return ( - !failsPlatinumLicenseCheck && ( - - ) - ); - })} - - - ); -}); - -AdvancedPolicyForms.displayName = 'AdvancedPolicyForms'; - -const PolicyAdvanced = React.memo( - ({ - configPath, - firstSupportedVersion, - lastSupportedVersion, - documentation, - }: { - configPath: string[]; - firstSupportedVersion: string; - lastSupportedVersion?: string; - documentation: string; - }) => { - const showEditableFormFields = useShowEditableFormFields(); - const dispatch = useDispatch(); - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const onChange = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - setValue( - newPayload as unknown as Record, - event.target.value, - configPath - ); - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [dispatch, policyDetailsConfig, configPath] - ); - - const value = - policyDetailsConfig && - getValue(policyDetailsConfig as unknown as Record, configPath); - - return ( - <> - - {configPath.join('.')} - {documentation && ( - - - - )} - - } - labelAppend={ - - {lastSupportedVersion - ? `${firstSupportedVersion}-${lastSupportedVersion}` - : `${firstSupportedVersion}+`} - - } - > - - - - ); - } -); - -PolicyAdvanced.displayName = 'PolicyAdvanced'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx index 020ef18ed0d8b..58bb5189332fe 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx @@ -28,9 +28,6 @@ import { policyListApiPathHandlers } from '../store/test_mock_utils'; import { PolicyDetails } from './policy_details'; import { APP_UI_ID } from '../../../../../common/constants'; -jest.mock('./policy_forms/components/policy_form_layout', () => ({ - PolicyFormLayout: () => <>, -})); jest.mock('../../../../common/components/user_privileges'); const useUserPrivilegesMock = useUserPrivileges as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx index 04d9e14efa5b9..5adf40105255c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx @@ -15,7 +15,7 @@ import { } from '@elastic/eui'; import { usePolicyDetailsSelector } from './policy_hooks'; import { policyDetails, agentStatusSummary, apiError } from '../store/policy_details/selectors'; -import { AgentsSummary } from './agents_summary'; +import { AgentsSummary } from './components/agents_summary'; import { PolicyTabs } from './tabs'; import { AdministrationListPage } from '../../../components/administration_list_page'; import type { BackToExternalAppButtonProps } from '../../../components/back_to_external_app_button/back_to_external_app_button'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details_form.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details_form.tsx deleted file mode 100644 index 61947bc5982f4..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details_form.tsx +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButtonEmpty, EuiSkeletonText, EuiSpacer, EuiText } from '@elastic/eui'; -import React, { memo, useCallback, useState } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; -import { useUserPrivileges } from '../../../../common/components/user_privileges'; -import { MalwareProtections } from './policy_forms/protections/malware'; -import { MemoryProtection } from './policy_forms/protections/memory'; -import { BehaviorProtection } from './policy_forms/protections/behavior'; -import { LinuxEvents, MacEvents, WindowsEvents } from './policy_forms/events'; -import { AdvancedPolicyForms } from './policy_advanced'; -import { AntivirusRegistrationForm } from './components/antivirus_registration_form'; -import { AttackSurfaceReductionForm } from './components/attack_surface_reduction_form'; -import { Ransomware } from './policy_forms/protections/ransomware'; -import { LockedPolicyCard } from './policy_forms/locked_card'; -import { useLicense } from '../../../../common/hooks/use_license'; - -const LOCKED_CARD_RAMSOMWARE_TITLE = i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.ransomware', - { - defaultMessage: 'Ransomware', - } -); - -const LOCKED_CARD_MEMORY_TITLE = i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.memory', - { - defaultMessage: 'Memory Threat', - } -); - -const LOCKED_CARD_BEHAVIOR_TITLE = i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.behavior', - { - defaultMessage: 'Malicious Behavior', - } -); - -const LOCKED_CARD_ATTACK_SURFACE_REDUCTION = i18n.translate( - 'xpack.securitySolution.endpoint.policy.details.attack_surface_reduction', - { - defaultMessage: 'Attack Surface Reduction', - } -); - -export const PolicyDetailsForm = memo(() => { - const [showAdvancedPolicy, setShowAdvancedPolicy] = useState(false); - const handleAdvancedPolicyClick = useCallback(() => { - setShowAdvancedPolicy(!showAdvancedPolicy); - }, [showAdvancedPolicy]); - const isPlatinumPlus = useLicense().isPlatinumPlus(); - const { loading: authzLoading } = useUserPrivileges().endpointPrivileges; - - if (authzLoading) { - return ; - } - - return ( - <> - -

- -

-
- - - - - {isPlatinumPlus ? : } - - {isPlatinumPlus ? ( - - ) : ( - - )} - - {isPlatinumPlus ? ( - - ) : ( - - )} - - {isPlatinumPlus ? ( - - ) : ( - - )} - - - -

- -

-
- - - - - - - - - - - - - - - - - {showAdvancedPolicy && } - - ); -}); -PolicyDetailsForm.displayName = 'PolicyDetailsForm'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx deleted file mode 100644 index 6d07b3784c6c2..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import type { ReactWrapper } from 'enzyme'; -import { mount } from 'enzyme'; - -import { PolicyFormLayout } from './policy_form_layout'; -import '../../../../../../common/mock/match_media'; -import { EndpointDocGenerator } from '../../../../../../../common/endpoint/generate_data'; -import type { AppContextTestRender } from '../../../../../../common/mock/endpoint'; -import { - createAppRootMockRenderer, - resetReactDomCreatePortalMock, -} from '../../../../../../common/mock/endpoint'; -import { getPolicyDetailPath, getPoliciesPath } from '../../../../../common/routing'; -import { policyListApiPathHandlers } from '../../../store/test_mock_utils'; -import { licenseService } from '../../../../../../common/hooks/use_license'; -import { PACKAGE_POLICY_API_ROOT, AGENT_API_ROUTES } from '@kbn/fleet-plugin/common'; -import { useUserPrivileges as _useUserPrivileges } from '../../../../../../common/components/user_privileges'; -import { getUserPrivilegesMockDefaultValue } from '../../../../../../common/components/user_privileges/__mocks__'; - -jest.mock('../../../../../../common/hooks/use_license'); -jest.mock('../../../../../../common/components/user_privileges'); - -const useUserPrivilegesMock = _useUserPrivileges as jest.Mock; - -describe('Policy Form Layout', () => { - type FindReactWrapperResponse = ReturnType['find']>; - - const policyDetailsPathUrl = getPolicyDetailPath('1'); - const policyListPath = getPoliciesPath(); - const sleep = (ms = 100) => new Promise((wakeup) => setTimeout(wakeup, ms)); - const generator = new EndpointDocGenerator(); - let history: AppContextTestRender['history']; - let coreStart: AppContextTestRender['coreStart']; - let http: typeof coreStart.http; - let render: (ui: Parameters[0]) => ReturnType; - let policyPackagePolicy: ReturnType; - let policyFormLayoutView: ReturnType; - - beforeAll(() => resetReactDomCreatePortalMock()); - - beforeEach(() => { - const appContextMockRenderer = createAppRootMockRenderer(); - const AppWrapper = appContextMockRenderer.AppWrapper; - - ({ history, coreStart } = appContextMockRenderer); - render = (ui) => mount(ui, { wrappingComponent: AppWrapper }); - http = coreStart.http; - }); - - afterEach(() => { - if (policyFormLayoutView) { - policyFormLayoutView.unmount(); - } - jest.clearAllMocks(); - }); - - describe('when displayed with valid id', () => { - let asyncActions: Promise = Promise.resolve(); - - beforeEach(async () => { - policyPackagePolicy = generator.generatePolicyPackagePolicy(); - policyPackagePolicy.id = '1'; - - const policyListApiHandlers = policyListApiPathHandlers(); - - http.get.mockImplementation((...args) => { - const [path] = args; - if (typeof path === 'string') { - // GET datasouce - if (path === `${PACKAGE_POLICY_API_ROOT}/1`) { - asyncActions = asyncActions.then(async (): Promise => sleep()); - return Promise.resolve({ - item: policyPackagePolicy, - success: true, - }); - } - - // GET Agent status for agent policy - if (path === `${AGENT_API_ROUTES.STATUS_PATTERN}`) { - asyncActions = asyncActions.then(async () => sleep()); - return Promise.resolve({ - results: { events: 0, total: 5, online: 3, error: 1, offline: 1 }, - success: true, - }); - } - - // Get package data - // Used in tests that route back to the list - if (policyListApiHandlers[path]) { - asyncActions = asyncActions.then(async () => sleep()); - return Promise.resolve(policyListApiHandlers[path]()); - } - } - - return Promise.reject(new Error(`unknown API call (not MOCKED): ${path}`)); - }); - history.push(policyDetailsPathUrl); - policyFormLayoutView = render(); - - await asyncActions; - policyFormLayoutView.update(); - }); - - it('should NOT display timeline', async () => { - expect(policyFormLayoutView.find('flyoutOverlay')).toHaveLength(0); - }); - - it('should display cancel button', async () => { - const cancelbutton = policyFormLayoutView.find( - 'EuiButtonEmpty[data-test-subj="policyDetailsCancelButton"]' - ); - expect(cancelbutton).toHaveLength(1); - expect(cancelbutton.text()).toEqual('Cancel'); - }); - it('should redirect to policy list when cancel button is clicked', async () => { - const cancelbutton = policyFormLayoutView.find( - 'EuiButtonEmpty[data-test-subj="policyDetailsCancelButton"]' - ); - expect(history.location.pathname).toEqual(policyDetailsPathUrl); - cancelbutton.simulate('click', { button: 0 }); - const navigateToAppMockedCalls = coreStart.application.navigateToApp.mock.calls; - expect(navigateToAppMockedCalls[navigateToAppMockedCalls.length - 1]).toEqual([ - 'securitySolutionUI', - { path: policyListPath }, - ]); - }); - it('should display save button', async () => { - const saveButton = policyFormLayoutView.find( - 'EuiButton[data-test-subj="policyDetailsSaveButton"]' - ); - expect(saveButton).toHaveLength(1); - expect(saveButton.text()).toEqual('Save'); - }); - it('should display beta badge', async () => { - const saveButton = policyFormLayoutView.find('EuiBetaBadge'); - expect(saveButton).toHaveLength(1); - expect(saveButton.text()).toEqual('beta'); - }); - - it('should display minimum Agent version number for User Notification', async () => { - const minVersionsMap = [ - ['malware', '7.11'], - ['ransomware', '7.12'], - ['behavior', '7.15'], - ['memory', '7.15'], - ]; - - for (const [protection, minVersion] of minVersionsMap) { - expect( - policyFormLayoutView - .find(`EuiPanel[data-test-subj="${protection}ProtectionsForm"]`) - .find('EuiText[data-test-subj="policySupportedVersions"]') - .text() - ).toEqual(`Agent version ${minVersion}+`); - } - }); - - it('"Register as antivirus" should be only available for Windows', () => { - const antivirusRegistrationFormTextContent = policyFormLayoutView - .find('EuiPanel[data-test-subj="antivirusRegistrationForm"]') - .text(); - - expect(antivirusRegistrationFormTextContent).toContain('Windows'); - expect(antivirusRegistrationFormTextContent).not.toContain('Linux'); - expect(antivirusRegistrationFormTextContent).not.toContain('Mac'); - - expect(antivirusRegistrationFormTextContent).toContain( - 'Toggle on to register Elastic as an official Antivirus solution for Windows OS. This will also disable Windows Defender.' - ); - }); - - describe('Advanced settings', () => { - let showHideAdvancedSettingsButton: ReactWrapper; - - beforeEach(() => { - showHideAdvancedSettingsButton = policyFormLayoutView.find( - 'EuiButtonEmpty[data-test-subj="advancedPolicyButton"]' - ); - }); - - it('should display "Show advanced settings" button, and hide advanced options on default', () => { - expect(showHideAdvancedSettingsButton.text()).toEqual('Show advanced settings'); - expect( - policyFormLayoutView.find('EuiPanel[data-test-subj="advancedPolicyPanel"]').length - ).toEqual(0); - }); - - it('clicking on "Show/Hide advanced settings" should show/hide advanced settings', () => { - showHideAdvancedSettingsButton.simulate('click'); - - expect(showHideAdvancedSettingsButton.text()).toEqual('Hide advanced settings'); - expect( - policyFormLayoutView.find('EuiPanel[data-test-subj="advancedPolicyPanel"]').length - ).toEqual(1); - - showHideAdvancedSettingsButton.simulate('click'); - - expect( - policyFormLayoutView.find('EuiPanel[data-test-subj="advancedPolicyPanel"]').length - ).toEqual(0); - }); - - it('should display a warning message', () => { - showHideAdvancedSettingsButton.simulate('click'); - - expect( - policyFormLayoutView.find('div[data-test-subj="policyAdvancedSettingsWarning"]').text() - ).toContain( - `This section contains policy values that support advanced use cases. If not configured - properly, these values can cause unpredictable behavior. Please consult documentation - carefully or contact support before editing these values.` - ); - }); - - it('every row should contain a tooltip', () => { - showHideAdvancedSettingsButton.simulate('click'); - - policyFormLayoutView - .find('EuiPanel[data-test-subj="advancedPolicyPanel"]') - .find('EuiFormRow') - .forEach((row) => { - expect(row.find('EuiIconTip').length).toEqual(1); - }); - }); - }); - - describe('when the save button is clicked', () => { - let saveButton: FindReactWrapperResponse; - let confirmModal: FindReactWrapperResponse; - let modalCancelButton: FindReactWrapperResponse; - let modalConfirmButton: FindReactWrapperResponse; - - beforeEach(async () => { - await asyncActions; - policyFormLayoutView.update(); - saveButton = policyFormLayoutView.find('button[data-test-subj="policyDetailsSaveButton"]'); - saveButton.simulate('click'); - policyFormLayoutView.update(); - confirmModal = policyFormLayoutView.find( - 'EuiConfirmModal[data-test-subj="policyDetailsConfirmModal"]' - ); - modalCancelButton = confirmModal.find('button[data-test-subj="confirmModalCancelButton"]'); - modalConfirmButton = confirmModal.find( - 'button[data-test-subj="confirmModalConfirmButton"]' - ); - http.put.mockImplementation((...args) => { - asyncActions = asyncActions.then(async () => sleep()); - const [path] = args; - if (typeof path === 'string') { - if (path === `${PACKAGE_POLICY_API_ROOT}/1`) { - return Promise.resolve({ - item: policyPackagePolicy, - success: true, - }); - } - } - - return Promise.reject(new Error('unknown PUT path!')); - }); - }); - - it('should show a modal confirmation', () => { - expect(confirmModal).toHaveLength(1); - expect( - confirmModal.find('[data-test-subj="confirmModalTitleText"]').first().text() - ).toEqual('Save and deploy changes'); - expect(modalCancelButton.text()).toEqual('Cancel'); - expect(modalConfirmButton.text()).toEqual('Save and deploy changes'); - }); - it('should show info callout if policy is in use', () => { - const warningCallout = confirmModal.find( - 'EuiCallOut[data-test-subj="policyDetailsWarningCallout"]' - ); - expect(warningCallout).toHaveLength(1); - expect(warningCallout.text()).toEqual( - 'This action will update 5 endpointsSaving these changes will apply updates to all endpoints assigned to this agent policy.' - ); - }); - it('should close dialog if cancel button is clicked', () => { - modalCancelButton.simulate('click'); - expect( - policyFormLayoutView.find('EuiConfirmModal[data-test-subj="policyDetailsConfirmModal"]') - ).toHaveLength(0); - }); - it('should update policy and show success notification when confirm button is clicked', async () => { - modalConfirmButton.simulate('click'); - policyFormLayoutView.update(); - // Modal should be closed - expect( - policyFormLayoutView.find('EuiConfirmModal[data-test-subj="policyDetailsConfirmModal"]') - ).toHaveLength(0); - - // API should be called - await asyncActions; - expect(http.put.mock.calls[0][0]).toEqual(`${PACKAGE_POLICY_API_ROOT}/1`); - policyFormLayoutView.update(); - - // Toast notification should be shown - const toastAddMock = coreStart.notifications.toasts.addSuccess.mock; - expect(toastAddMock.calls).toHaveLength(1); - expect(toastAddMock.calls[0][0]).toMatchObject({ - title: 'Success!', - text: expect.any(Function), - }); - }); - it('should show an error notification toast if update fails', async () => { - policyPackagePolicy.id = 'invalid'; - modalConfirmButton.simulate('click'); - - await asyncActions; - policyFormLayoutView.update(); - - // Toast notification should be shown - const toastAddMock = coreStart.notifications.toasts.addDanger.mock; - expect(toastAddMock.calls).toHaveLength(1); - expect(toastAddMock.calls[0][0]).toMatchObject({ - title: 'Failed!', - text: expect.any(String), - }); - }); - }); - - describe('when the subscription tier is platinum or higher', () => { - beforeEach(() => { - (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(true); - policyFormLayoutView = render(); - }); - - it('malware popup, message customization options and tooltip are shown', () => { - // use query for finding stuff, if it doesn't find it, just returns null - const userNotificationCheckbox = policyFormLayoutView.find( - 'EuiCheckbox[data-test-subj="malwareUserNotificationCheckbox"]' - ); - const userNotificationCustomMessageTextArea = policyFormLayoutView.find( - 'EuiTextArea[data-test-subj="malwareUserNotificationCustomMessage"]' - ); - const tooltip = policyFormLayoutView.find('EuiIconTip[data-test-subj="malwareTooltip"]'); - expect(userNotificationCheckbox).toHaveLength(1); - expect(userNotificationCustomMessageTextArea).toHaveLength(1); - expect(tooltip).toHaveLength(1); - }); - - it('memory protection card and user notification checkbox are shown', () => { - const memory = policyFormLayoutView.find( - 'EuiPanel[data-test-subj="memoryProtectionsForm"]' - ); - const userNotificationCheckbox = policyFormLayoutView.find( - 'EuiCheckbox[data-test-subj="memory_protectionUserNotificationCheckbox"]' - ); - - expect(memory).toHaveLength(1); - expect(userNotificationCheckbox).toHaveLength(1); - }); - - it('behavior protection card and user notification checkbox are shown', () => { - const behavior = policyFormLayoutView.find( - 'EuiPanel[data-test-subj="behaviorProtectionsForm"]' - ); - const userNotificationCheckbox = policyFormLayoutView.find( - 'EuiCheckbox[data-test-subj="behavior_protectionUserNotificationCheckbox"]' - ); - - expect(behavior).toHaveLength(1); - expect(userNotificationCheckbox).toHaveLength(1); - }); - - it('ransomware card is shown', () => { - const ransomware = policyFormLayoutView.find( - 'EuiPanel[data-test-subj="ransomwareProtectionsForm"]' - ); - expect(ransomware).toHaveLength(1); - }); - }); - - describe('when the subscription tier is gold or lower', () => { - beforeEach(() => { - (licenseService.isPlatinumPlus as jest.Mock).mockReturnValue(false); - policyFormLayoutView = render(); - }); - - it('malware popup, message customization options, and tooltip are hidden', () => { - const userNotificationCheckbox = policyFormLayoutView.find( - 'EuiCheckbox[data-test-subj="malwareUserNotificationCheckbox"]' - ); - const userNotificationCustomMessageTextArea = policyFormLayoutView.find( - 'EuiTextArea[data-test-subj="malwareUserNotificationCustomMessage"]' - ); - const tooltip = policyFormLayoutView.find('EuiIconTip[data-test-subj="malwareTooltip"]'); - expect(userNotificationCheckbox).toHaveLength(0); - expect(userNotificationCustomMessageTextArea).toHaveLength(0); - expect(tooltip).toHaveLength(0); - }); - - it('memory protection card, and user notification checkbox are hidden', () => { - const memory = policyFormLayoutView.find( - 'EuiPanel[data-test-subj="memoryProtectionsForm"]' - ); - expect(memory).toHaveLength(0); - const userNotificationCheckbox = policyFormLayoutView.find( - 'EuiCheckbox[data-test-subj="memoryUserNotificationCheckbox"]' - ); - expect(userNotificationCheckbox).toHaveLength(0); - }); - - it('ransomware card is hidden', () => { - const ransomware = policyFormLayoutView.find( - 'EuiPanel[data-test-subj="ransomwareProtectionsForm"]' - ); - expect(ransomware).toHaveLength(0); - }); - - it('shows the locked card in place of paid features', () => { - const lockedCard = policyFormLayoutView.find('EuiCard[data-test-subj="lockedPolicyCard"]'); - expect(lockedCard).toHaveLength(4); - }); - - it('locked card has "Upgrade now" link to cloud server', () => { - const upgradeLinks = policyFormLayoutView.find( - 'EuiLink[data-test-subj="upgradeNowCloudDeploymentLink"]' - ); - upgradeLinks.forEach((link) => { - expect(link.prop('href')).toEqual('https://www.elastic.co/cloud/'); - }); - }); - }); - - describe('and user has only READ privilege', () => { - beforeEach(() => { - const mockedPrivileges = getUserPrivilegesMockDefaultValue(); - mockedPrivileges.endpointPrivileges.canWritePolicyManagement = false; - mockedPrivileges.endpointPrivileges.canAccessFleet = false; - - useUserPrivilegesMock.mockReturnValue(mockedPrivileges); - - policyFormLayoutView = render(); - }); - - afterEach(() => { - useUserPrivilegesMock.mockImplementation(getUserPrivilegesMockDefaultValue); - }); - - it('should not display the Save button', () => { - expect( - policyFormLayoutView.find('EuiButton[data-test-subj="policyDetailsSaveButton"]') - ).toHaveLength(0); - }); - - it('should display all form controls as disabled', () => { - policyFormLayoutView - .find('button[data-test-subj="advancedPolicyButton"]') - .simulate('click'); - - const inputElements = policyFormLayoutView.find('input'); - - expect(inputElements.length).toBeGreaterThan(0); - - inputElements.forEach((element) => { - expect(element.prop('disabled')).toBe(true); - }); - }); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_radio.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_radio.tsx deleted file mode 100644 index ec69dc8115b02..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_radio.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, useMemo } from 'react'; -import { useDispatch } from 'react-redux'; -import { cloneDeep } from 'lodash'; -import { htmlIdGenerator, EuiRadio } from '@elastic/eui'; -import type { ImmutableArray, UIPolicyConfig } from '../../../../../../../common/endpoint/types'; -import { ProtectionModes } from '../../../../../../../common/endpoint/types'; -import type { MacPolicyProtection, LinuxPolicyProtection, PolicyProtection } from '../../../types'; -import { useShowEditableFormFields, usePolicyDetailsSelector } from '../../policy_hooks'; -import { policyConfig } from '../../../store/policy_details/selectors'; -import type { AppAction } from '../../../../../../common/store/actions'; -import { useLicense } from '../../../../../../common/hooks/use_license'; - -export const ProtectionRadio = React.memo( - ({ - protection, - protectionMode, - osList, - label, - }: { - protection: PolicyProtection; - protectionMode: ProtectionModes; - osList: ImmutableArray>; - label: string; - }) => { - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const dispatch = useDispatch<(action: AppAction) => void>(); - const radioButtonId = useMemo(() => htmlIdGenerator()(), []); - const selected = policyDetailsConfig && policyDetailsConfig.windows[protection].mode; - const isPlatinumPlus = useLicense().isPlatinumPlus(); - const showEditableFormFields = useShowEditableFormFields(); - - const handleRadioChange = useCallback(() => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - for (const os of osList) { - if (os === 'windows') { - newPayload[os][protection].mode = protectionMode; - } else if (os === 'mac') { - newPayload[os][protection as MacPolicyProtection].mode = protectionMode; - } else if (os === 'linux') { - newPayload[os][protection as LinuxPolicyProtection].mode = protectionMode; - } - if (isPlatinumPlus) { - if (os === 'windows') { - if (protectionMode === ProtectionModes.prevent) { - newPayload[os].popup[protection].enabled = true; - } else { - newPayload[os].popup[protection].enabled = false; - } - } else if (os === 'mac') { - if (protectionMode === ProtectionModes.prevent) { - newPayload[os].popup[protection as MacPolicyProtection].enabled = true; - } else { - newPayload[os].popup[protection as MacPolicyProtection].enabled = false; - } - } else if (os === 'linux') { - if (protectionMode === ProtectionModes.prevent) { - newPayload[os].popup[protection as LinuxPolicyProtection].enabled = true; - } else { - newPayload[os].popup[protection as LinuxPolicyProtection].enabled = false; - } - } - } - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, [dispatch, protectionMode, policyDetailsConfig, isPlatinumPlus, osList, protection]); - - /** - * Passing an arbitrary id because EuiRadio - * requires an id if label is passed - */ - - return ( - - ); - } -); - -ProtectionRadio.displayName = 'ProtectionRadio'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx deleted file mode 100644 index 20536a1905382..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/protection_switch.tsx +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback } from 'react'; -import { useDispatch } from 'react-redux'; -import { i18n } from '@kbn/i18n'; -import { EuiSwitch } from '@elastic/eui'; -import { cloneDeep } from 'lodash'; -import { useLicense } from '../../../../../../common/hooks/use_license'; -import { policyConfig } from '../../../store/policy_details/selectors'; -import { useShowEditableFormFields, usePolicyDetailsSelector } from '../../policy_hooks'; -import type { AppAction } from '../../../../../../common/store/actions'; -import type { - ImmutableArray, - UIPolicyConfig, - AdditionalOnSwitchChangeParams, -} from '../../../../../../../common/endpoint/types'; -import { ProtectionModes } from '../../../../../../../common/endpoint/types'; -import type { PolicyProtection, MacPolicyProtection, LinuxPolicyProtection } from '../../../types'; - -export const ProtectionSwitch = React.memo( - ({ - protection, - protectionLabel, - osList, - additionalOnSwitchChange, - }: { - protection: PolicyProtection; - protectionLabel?: string; - osList: ImmutableArray>; - additionalOnSwitchChange?: ({ - value, - policyConfigData, - protectionOsList, - }: AdditionalOnSwitchChangeParams) => UIPolicyConfig; - }) => { - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const isPlatinumPlus = useLicense().isPlatinumPlus(); - const showEditableFormFields = useShowEditableFormFields(); - const dispatch = useDispatch<(action: AppAction) => void>(); - const selected = policyDetailsConfig && policyDetailsConfig.windows[protection].mode; - - const handleSwitchChange = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - if (event.target.checked === false) { - for (const os of osList) { - if (os === 'windows') { - newPayload[os][protection].mode = ProtectionModes.off; - } else if (os === 'mac') { - newPayload[os][protection as MacPolicyProtection].mode = ProtectionModes.off; - } else if (os === 'linux') { - newPayload[os][protection as LinuxPolicyProtection].mode = ProtectionModes.off; - } - if (isPlatinumPlus) { - if (os === 'windows') { - newPayload[os].popup[protection].enabled = event.target.checked; - } else if (os === 'mac') { - newPayload[os].popup[protection as MacPolicyProtection].enabled = - event.target.checked; - } else if (os === 'linux') { - newPayload[os].popup[protection as LinuxPolicyProtection].enabled = - event.target.checked; - } - } - } - } else { - for (const os of osList) { - if (os === 'windows') { - newPayload[os][protection].mode = ProtectionModes.prevent; - } else if (os === 'mac') { - newPayload[os][protection as MacPolicyProtection].mode = ProtectionModes.prevent; - } else if (os === 'linux') { - newPayload[os][protection as LinuxPolicyProtection].mode = ProtectionModes.prevent; - } - if (isPlatinumPlus) { - if (os === 'windows') { - newPayload[os].popup[protection].enabled = event.target.checked; - } else if (os === 'mac') { - newPayload[os].popup[protection as MacPolicyProtection].enabled = - event.target.checked; - } else if (os === 'linux') { - newPayload[os].popup[protection as LinuxPolicyProtection].enabled = - event.target.checked; - } - } - } - } - if (additionalOnSwitchChange) { - dispatch({ - type: 'userChangedPolicyConfig', - payload: { - policyConfig: additionalOnSwitchChange({ - value: event.target.checked, - policyConfigData: newPayload, - protectionOsList: osList, - }), - }, - }); - } else { - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - } - }, - [dispatch, policyDetailsConfig, isPlatinumPlus, protection, osList, additionalOnSwitchChange] - ); - - return ( - - ); - } -); - -ProtectionSwitch.displayName = 'ProtectionSwitch'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/radio_buttons.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/radio_buttons.tsx deleted file mode 100644 index ce4d86e037899..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/radio_buttons.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useMemo } from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiSpacer, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; -import type { - Immutable, - ImmutableArray, - UIPolicyConfig, -} from '../../../../../../../common/endpoint/types'; -import { ProtectionModes } from '../../../../../../../common/endpoint/types'; -import type { PolicyProtection } from '../../../types'; -import { ConfigFormHeading } from '../../components/config_form'; -import { ProtectionRadio } from './protection_radio'; - -export const RadioButtons = React.memo( - ({ - protection, - osList, - }: { - protection: PolicyProtection; - osList: ImmutableArray>; - }) => { - const radios: Immutable< - Array<{ - id: ProtectionModes; - label: string; - }> - > = useMemo(() => { - return [ - { - id: ProtectionModes.detect, - label: i18n.translate('xpack.securitySolution.endpoint.policy.details.detect', { - defaultMessage: 'Detect', - }), - }, - { - id: ProtectionModes.prevent, - label: i18n.translate('xpack.securitySolution.endpoint.policy.details.prevent', { - defaultMessage: 'Prevent', - }), - }, - ]; - }, []); - - return ( - <> - - - - - - - - - - - - - - ); - } -); - -RadioButtons.displayName = 'RadioButtons'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/supported_version.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/supported_version.tsx deleted file mode 100644 index b3cf322f70fac..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/supported_version.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiText } from '@elastic/eui'; -import { popupVersionsMap } from '../protections/popup_options_to_versions'; - -export const SupportedVersionNotice = ({ optionName }: { optionName: string }) => { - const version = popupVersionsMap.get(optionName); - if (!version) { - return null; - } - - return ( - - - - - - ); -}; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/user_notification.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/user_notification.tsx deleted file mode 100644 index baecfef415a02..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/user_notification.tsx +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback } from 'react'; -import { useDispatch } from 'react-redux'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { cloneDeep } from 'lodash'; -import { - EuiSpacer, - EuiFlexItem, - EuiFlexGroup, - EuiCheckbox, - EuiIconTip, - EuiText, - EuiTextArea, -} from '@elastic/eui'; -import type { ImmutableArray, UIPolicyConfig } from '../../../../../../../common/endpoint/types'; -import { ProtectionModes } from '../../../../../../../common/endpoint/types'; -import type { PolicyProtection, MacPolicyProtection, LinuxPolicyProtection } from '../../../types'; -import { ConfigFormHeading } from '../../components/config_form'; -import { useShowEditableFormFields, usePolicyDetailsSelector } from '../../policy_hooks'; -import { policyConfig } from '../../../store/policy_details/selectors'; -import type { AppAction } from '../../../../../../common/store/actions'; -import { SupportedVersionNotice } from './supported_version'; - -export const UserNotification = React.memo( - ({ - protection, - osList, - }: { - protection: PolicyProtection; - osList: ImmutableArray>; - }) => { - const showEditableFormFields = useShowEditableFormFields(); - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const dispatch = useDispatch<(action: AppAction) => void>(); - const selected = policyDetailsConfig && policyDetailsConfig.windows[protection].mode; - const userNotificationSelected = - policyDetailsConfig && policyDetailsConfig.windows.popup[protection].enabled; - const userNotificationMessage = - policyDetailsConfig && policyDetailsConfig.windows.popup[protection].message; - - const handleUserNotificationCheckbox = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - for (const os of osList) { - if (os === 'windows') { - newPayload[os].popup[protection].enabled = event.target.checked; - } else if (os === 'mac') { - newPayload[os].popup[protection as MacPolicyProtection].enabled = - event.target.checked; - } else if (os === 'linux') { - newPayload[os].popup[protection as LinuxPolicyProtection].enabled = - event.target.checked; - } - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [policyDetailsConfig, dispatch, protection, osList] - ); - - const handleCustomUserNotification = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = cloneDeep(policyDetailsConfig); - for (const os of osList) { - if (os === 'windows') { - newPayload[os].popup[protection].message = event.target.value; - } else if (os === 'mac') { - newPayload[os].popup[protection as MacPolicyProtection].message = event.target.value; - } else if (os === 'linux') { - newPayload[os].popup[protection as LinuxPolicyProtection].message = - event.target.value; - } - } - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [policyDetailsConfig, dispatch, protection, osList] - ); - - const tooltipProtectionText = (protectionType: PolicyProtection) => { - if (protectionType === 'memory_protection') { - return i18n.translate( - 'xpack.securitySolution.endpoint.policyDetail.memoryProtectionTooltip', - { - defaultMessage: 'memory threat', - } - ); - } else if (protectionType === 'behavior_protection') { - return i18n.translate( - 'xpack.securitySolution.endpoint.policyDetail.behaviorProtectionTooltip', - { - defaultMessage: 'malicious behavior', - } - ); - } else { - return protectionType; - } - }; - - const tooltipBracketText = (protectionType: PolicyProtection) => { - if (protectionType === 'memory_protection' || protection === 'behavior_protection') { - return i18n.translate('xpack.securitySolution.endpoint.policyDetail.rule', { - defaultMessage: 'rule', - }); - } else { - return i18n.translate('xpack.securitySolution.endpoint.policyDetail.filename', { - defaultMessage: 'filename', - }); - } - }; - - return ( - <> - - - - - - - - {userNotificationSelected && ( - <> - - - - -

- -

-
-
- - - - - - - } - /> - -
- - - - )} - - ); - } -); - -UserNotification.displayName = 'UserNotification'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/locked_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/locked_card.tsx deleted file mode 100644 index 5d503a9667d39..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/locked_card.tsx +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo } from 'react'; -import { - EuiCard, - EuiIcon, - EuiTextColor, - EuiLink, - EuiFlexGroup, - EuiFlexItem, - EuiText, -} from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import styled from 'styled-components'; -import { i18n } from '@kbn/i18n'; - -const LockedPolicyDiv = styled.div` - .euiCard__betaBadgeWrapper { - .euiCard__betaBadge { - width: auto; - } - } - .lockedCardDescription { - padding: 0 33.3%; - } -`; - -export const LockedPolicyCard = memo(({ title }: { title: string }) => { - return ( - - } - title={ -

- {title} -

- } - description={false} - > - - - -

- - - -

-
- -

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

-
-
-
-
-
- ); -}); -LockedPolicyCard.displayName = 'LockedPolicyCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/behavior.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/behavior.tsx deleted file mode 100644 index 1e9efefe4ac60..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/behavior.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiCallOut, EuiSpacer } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { OperatingSystem } from '@kbn/securitysolution-utils'; -import type { Immutable } from '../../../../../../../common/endpoint/types'; -import { PolicyOperatingSystem } from '../../../../../../../common/endpoint/types'; -import type { BehaviorProtectionOSes } from '../../../types'; -import { ConfigForm } from '../../components/config_form'; -import { RadioButtons } from '../components/radio_buttons'; -import { UserNotification } from '../components/user_notification'; -import { ProtectionSwitch } from '../components/protection_switch'; -import { APP_UI_ID } from '../../../../../../../common/constants'; -import { LinkToApp } from '../../../../../../common/components/endpoint/link_to_app'; -import { SecurityPageName } from '../../../../../../app/types'; - -/** The Behavior Protections form for policy details - * which will configure for all relevant OSes. - */ -export const BehaviorProtection = React.memo(() => { - const OSes: Immutable = [ - PolicyOperatingSystem.windows, - PolicyOperatingSystem.mac, - PolicyOperatingSystem.linux, - ]; - const protection = 'behavior_protection'; - const protectionLabel = i18n.translate( - 'xpack.securitySolution.endpoint.policy.protections.behavior', - { - defaultMessage: 'Malicious behavior protections', - } - ); - return ( - - } - > - - - - - - - - ), - }} - /> - - - ); -}); - -BehaviorProtection.displayName = 'BehaviorProtection'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx deleted file mode 100644 index a9782c8a56a02..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/malware.tsx +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, useMemo } from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { - EuiCallOut, - EuiSpacer, - EuiSwitch, - EuiFlexGroup, - EuiFlexItem, - EuiIconTip, -} from '@elastic/eui'; -import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { useDispatch } from 'react-redux'; -import { cloneDeep } from 'lodash'; -import { APP_UI_ID } from '../../../../../../../common/constants'; -import { SecurityPageName } from '../../../../../../app/types'; -import type { - Immutable, - AdditionalOnSwitchChangeParams, - UIPolicyConfig, -} from '../../../../../../../common/endpoint/types'; -import { PolicyOperatingSystem } from '../../../../../../../common/endpoint/types'; -import type { MalwareProtectionOSes } from '../../../types'; -import { ConfigForm } from '../../components/config_form'; -import { LinkToApp } from '../../../../../../common/components/endpoint/link_to_app'; -import { useLicense } from '../../../../../../common/hooks/use_license'; -import { RadioButtons } from '../components/radio_buttons'; -import { UserNotification } from '../components/user_notification'; -import { ProtectionSwitch } from '../components/protection_switch'; -import { policyConfig } from '../../../store/policy_details/selectors'; -import { useShowEditableFormFields, usePolicyDetailsSelector } from '../../policy_hooks'; -import type { AppAction } from '../../../../../../common/store/actions'; - -/** The Malware Protections form for policy details - * which will configure for all relevant OSes. - */ -export const MalwareProtections = React.memo(() => { - const OSes: Immutable = useMemo( - () => [PolicyOperatingSystem.windows, PolicyOperatingSystem.mac, PolicyOperatingSystem.linux], - [] - ); - const protection = 'malware'; - const protectionLabel = i18n.translate( - 'xpack.securitySolution.endpoint.policy.protections.malware', - { - defaultMessage: 'Malware protections', - } - ); - const blocklistLabel = i18n.translate( - 'xpack.securitySolution.endpoint.policy.protections.blocklist', - { - defaultMessage: 'Blocklist enabled', - } - ); - const showEditableFormFields = useShowEditableFormFields(); - const isPlatinumPlus = useLicense().isPlatinumPlus(); - const dispatch = useDispatch<(action: AppAction) => void>(); - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - - const blocklistUpdate = ({ - value, - policyConfigData, - protectionOsList, - }: AdditionalOnSwitchChangeParams): UIPolicyConfig => { - const newPayload: UIPolicyConfig = cloneDeep(policyConfigData); - for (const os of protectionOsList) { - newPayload[os][protection].blocklist = value; - } - - return newPayload; - }; - - const handleBlocklistSwitchChange = useCallback( - (event) => { - if (policyDetailsConfig) { - const newPayload = blocklistUpdate({ - value: event.target.checked, - policyConfigData: cloneDeep(policyDetailsConfig), - protectionOsList: OSes, - }); - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: newPayload }, - }); - } - }, - [dispatch, OSes, policyDetailsConfig] - ); - - return ( - - } - > - - - - - - - - - - - } - /> - - - {isPlatinumPlus && } - - - - - - ), - }} - /> - - - ); -}); - -MalwareProtections.displayName = 'MalwareProtections'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/memory.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/memory.tsx deleted file mode 100644 index 5f9fec17d1749..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/memory.tsx +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiCallOut, EuiSpacer } from '@elastic/eui'; -import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { APP_UI_ID } from '../../../../../../../common/constants'; -import { SecurityPageName } from '../../../../../../app/types'; -import type { Immutable } from '../../../../../../../common/endpoint/types'; -import { PolicyOperatingSystem } from '../../../../../../../common/endpoint/types'; -import type { MemoryProtectionOSes } from '../../../types'; -import { ConfigForm } from '../../components/config_form'; -import { LinkToApp } from '../../../../../../common/components/endpoint/link_to_app'; -import { RadioButtons } from '../components/radio_buttons'; -import { UserNotification } from '../components/user_notification'; -import { ProtectionSwitch } from '../components/protection_switch'; - -/** The Memory Protections form for policy details - * which will configure for all relevant OSes. - */ -export const MemoryProtection = React.memo(() => { - const OSes: Immutable = [ - PolicyOperatingSystem.windows, - PolicyOperatingSystem.mac, - PolicyOperatingSystem.linux, - ]; - const protection = 'memory_protection'; - const protectionLabel = i18n.translate( - 'xpack.securitySolution.endpoint.policy.protections.memory', - { - defaultMessage: 'Memory threat protections', - } - ); - return ( - - } - > - - - - - - - - ), - }} - /> - - - ); -}); - -MemoryProtection.displayName = 'MemoryProtection'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/popup_options_to_versions.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/popup_options_to_versions.ts deleted file mode 100644 index 6458ee0eaf4d4..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/popup_options_to_versions.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -const popupVersions: Array<[string, string]> = [ - ['malware', '7.11+'], - ['ransomware', '7.12+'], - ['memory_protection', '7.15+'], - ['behavior_protection', '7.15+'], -]; - -export const popupVersionsMap: ReadonlyMap = new Map(popupVersions); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/ransomware.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/ransomware.tsx deleted file mode 100644 index 8b4cf8d4d4877..0000000000000 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/ransomware.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { EuiCallOut, EuiSpacer } from '@elastic/eui'; -import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { APP_UI_ID } from '../../../../../../../common/constants'; -import { SecurityPageName } from '../../../../../../app/types'; -import type { Immutable } from '../../../../../../../common/endpoint/types'; -import { PolicyOperatingSystem } from '../../../../../../../common/endpoint/types'; -import type { RansomwareProtectionOSes } from '../../../types'; -import { ConfigForm } from '../../components/config_form'; -import { LinkToApp } from '../../../../../../common/components/endpoint/link_to_app'; -import { RadioButtons } from '../components/radio_buttons'; -import { UserNotification } from '../components/user_notification'; -import { ProtectionSwitch } from '../components/protection_switch'; - -/** The Ransomware Protections form for policy details - * which will configure for all relevant OSes. - */ -export const Ransomware = React.memo(() => { - const OSes: Immutable = [PolicyOperatingSystem.windows]; - const protection = 'ransomware'; - const protectionLabel = i18n.translate( - 'xpack.securitySolution.endpoint.policy.protections.ransomware', - { - defaultMessage: 'Ransomware protections', - } - ); - - return ( - - } - > - - - - - - - - ), - }} - /> - - - ); -}); - -Ransomware.displayName = 'RansomwareProtections'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts index 26424205db010..19c3d9d6f3ea6 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_hooks.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { useCallback, useMemo } from 'react'; +import { useCallback } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; import { useSelector } from 'react-redux'; import { @@ -13,8 +13,6 @@ import { ENDPOINT_EVENT_FILTERS_LIST_ID, ENDPOINT_TRUSTED_APPS_LIST_ID, } from '@kbn/securitysolution-list-constants'; -import { useKibana } from '../../../../common/lib/kibana'; -import { useUserPrivileges } from '../../../../common/components/user_privileges'; import type { PolicyDetailsArtifactsPageLocation, PolicyDetailsState } from '../types'; import type { State } from '../../../../common/store'; import { @@ -28,7 +26,7 @@ import { getPolicyHostIsolationExceptionsPath, } from '../../../common/routing'; import { getCurrentArtifactsLocation, policyIdFromParams } from '../store/policy_details/selectors'; -import { APP_UI_ID, POLICIES_PATH } from '../../../../../common/constants'; +import { POLICIES_PATH } from '../../../../../common/constants'; /** * Narrows global state down to the PolicyDetailsState before calling the provided Policy Details Selector @@ -90,27 +88,3 @@ export const useIsPolicySettingsBarVisible = () => { window.location.pathname.includes('/settings') ); }; - -/** - * Indicates if user is granted Write access to Policy Management. This method differs from what - * `useUserPrivileges().endpointPrivileges.canWritePolicyManagement` in that it also checks if - * user has `canAccessFleet` if form is being displayed outside of Security Solution. - * This is to ensure that the Policy Form remains accessible when displayed inside of Fleet - * pages if the user does not have privileges to security solution policy management. - */ -export const useShowEditableFormFields = (): boolean => { - const { canWritePolicyManagement, canAccessFleet } = useUserPrivileges().endpointPrivileges; - const { getUrlForApp } = useKibana().services.application; - - const securitySolutionUrl = useMemo(() => { - return getUrlForApp(APP_UI_ID); - }, [getUrlForApp]); - - return useMemo(() => { - if (window.location.pathname.startsWith(securitySolutionUrl)) { - return canWritePolicyManagement; - } else { - return canAccessFleet; - } - }, [canAccessFleet, canWritePolicyManagement, securitySolutionUrl]); -}; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/advanced_section.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/advanced_section.tsx new file mode 100644 index 0000000000000..5e6a167b2ecac --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/advanced_section.tsx @@ -0,0 +1,239 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback, useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiCallOut, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiIconTip, + EuiPanel, + EuiSpacer, + EuiText, + EuiButtonEmpty, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { cloneDeep } from 'lodash'; +import { getEmptyValue } from '../../../../../../common/components/empty_value'; +import { useLicense } from '../../../../../../common/hooks/use_license'; +import { useTestIdGenerator } from '../../../../../hooks/use_test_id_generator'; +import type { PolicyFormComponentCommonProps } from '../types'; +import { AdvancedPolicySchema } from '../../../models/advanced_policy_schema'; + +function setValue(obj: Record, value: string, path: string[]) { + let newPolicyConfig = obj; + + // First set the value. + for (let i = 0; i < path.length - 1; i++) { + if (!newPolicyConfig[path[i]]) { + newPolicyConfig[path[i]] = {} as Record; + } + newPolicyConfig = newPolicyConfig[path[i]] as Record; + } + newPolicyConfig[path[path.length - 1]] = value; + + // Then, if the user is deleting the value, we need to ensure we clean up the config. + // We delete any sections that are empty, whether that be an empty string, empty object, or undefined. + if (value === '' || value === undefined) { + newPolicyConfig = obj; + for (let k = path.length; k >= 0; k--) { + const nextPath = path.slice(0, k); + for (let i = 0; i < nextPath.length - 1; i++) { + // Traverse and find the next section + newPolicyConfig = newPolicyConfig[nextPath[i]] as Record; + } + if ( + newPolicyConfig[nextPath[nextPath.length - 1]] === undefined || + newPolicyConfig[nextPath[nextPath.length - 1]] === '' || + Object.keys(newPolicyConfig[nextPath[nextPath.length - 1]] as object).length === 0 + ) { + // If we're looking at the `advanced` field, we leave it undefined as opposed to deleting it. + // This is because the UI looks for this field to begin rendering. + if (nextPath[nextPath.length - 1] === 'advanced') { + newPolicyConfig[nextPath[nextPath.length - 1]] = undefined; + // In all other cases, if field is empty, we'll delete it to clean up. + } else { + delete newPolicyConfig[nextPath[nextPath.length - 1]]; + } + newPolicyConfig = obj; + } else { + break; // We are looking at a non-empty section, so we can terminate. + } + } + } +} + +function getValue(obj: Record, path: string[]): string { + let currentPolicyConfig = obj; + + for (let i = 0; i < path.length - 1; i++) { + if (currentPolicyConfig[path[i]]) { + currentPolicyConfig = currentPolicyConfig[path[i]] as Record; + } else { + return ''; + } + } + return currentPolicyConfig[path[path.length - 1]] as string; +} + +const calloutTitle = i18n.translate( + 'xpack.securitySolution.endpoint.policy.advanced.calloutTitle', + { + defaultMessage: 'Proceed with caution!', + } +); + +const warningMessage = i18n.translate( + 'xpack.securitySolution.endpoint.policy.advanced.warningMessage', + { + defaultMessage: `This section contains policy values that support advanced use cases. If not configured + properly, these values can cause unpredictable behavior. Please consult documentation + carefully or contact support before editing these values.`, + } +); + +const HIDE = i18n.translate('xpack.securitySolution.endpoint.policy.advanced.hide', { + defaultMessage: 'Hide', +}); +const SHOW = i18n.translate('xpack.securitySolution.endpoint.policy.advanced.show', { + defaultMessage: 'Show', +}); + +export type AdvancedSectionProps = PolicyFormComponentCommonProps; + +export const AdvancedSection = memo( + ({ policy, mode, onChange, 'data-test-subj': dataTestSubj }) => { + const getTestId = useTestIdGenerator(dataTestSubj); + const [showAdvancedPolicy, setShowAdvancedPolicy] = useState(false); + const isPlatinumPlus = useLicense().isPlatinumPlus(); + + const isEditMode = mode === 'edit'; + + const handleAdvancedSettingsButtonClick = useCallback(() => { + setShowAdvancedPolicy((prevState) => !prevState); + }, []); + + const handleAdvancedSettingUpdate = useCallback( + (event) => { + const updatedPolicy = cloneDeep(policy); + + setValue( + updatedPolicy as unknown as Record, + event.target.value, + event.target.name.split('.') + ); + + onChange({ isValid: true, updatedPolicy }); + }, + [onChange, policy] + ); + + return ( +
+ + + + + + {showAdvancedPolicy && ( +
+ {isEditMode && ( + <> + +

{warningMessage}

+
+ + + )} + + +

+ +

+
+ + + {AdvancedPolicySchema.map( + ( + { + key, + documentation, + first_supported_version: firstVersion, + last_supported_version: lastVersion, + license, + }, + index + ) => { + if (!isPlatinumPlus && license === 'platinum') { + return ; + } + + const configPath = key.split('.'); + const value = getValue(policy as unknown as Record, configPath); + + return ( + + {key} + {documentation && ( + + + + )} + + } + labelAppend={ + + {lastVersion ? `${firstVersion}-${lastVersion}` : `${firstVersion}+`} + + } + > + {isEditMode ? ( + + ) : ( + {value || getEmptyValue()} + )} + + ); + } + )} + +
+ )} +
+ ); + } +); +AdvancedSection.displayName = 'AdvancedSection'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/antivirus_registration_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/antivirus_registration_card.tsx new file mode 100644 index 0000000000000..cc1ce6915ff50 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/antivirus_registration_card.tsx @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback } from 'react'; +import { OperatingSystem } from '@kbn/securitysolution-utils'; +import { i18n } from '@kbn/i18n'; +import { EuiSpacer, EuiSwitch, EuiText } from '@elastic/eui'; +import { cloneDeep } from 'lodash'; +import { useTestIdGenerator } from '../../../../../../hooks/use_test_id_generator'; +import { SettingCard } from '../setting_card'; +import type { PolicyFormComponentCommonProps } from '../../types'; + +const CARD_TITLE = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.type', + { + defaultMessage: 'Register as antivirus', + } +); + +const DESCRIPTON = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.explanation', + { + defaultMessage: + 'Toggle on to register Elastic as an official Antivirus solution for Windows OS. ' + + 'This will also disable Windows Defender.', + } +); + +const REGISTERED_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.type', + { + defaultMessage: 'Register as antivirus', + } +); + +const NOT_REGISTERED_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.antivirusRegistration.notRegisteredLabel', + { + defaultMessage: 'Do not register as antivirus', + } +); + +type AntivirusRegistrationCardProps = PolicyFormComponentCommonProps; + +export const AntivirusRegistrationCard = memo( + ({ policy, onChange, mode, 'data-test-subj': dataTestSubj }) => { + const getTestId = useTestIdGenerator(dataTestSubj); + const isChecked = policy.windows.antivirus_registration.enabled; + const isEditMode = mode === 'edit'; + const label = isChecked ? REGISTERED_LABEL : NOT_REGISTERED_LABEL; + + const handleSwitchChange = useCallback( + (event) => { + const updatedPolicy = cloneDeep(policy); + updatedPolicy.windows.antivirus_registration.enabled = event.target.checked; + + onChange({ isValid: true, updatedPolicy }); + }, + [onChange, policy] + ); + + return ( + + {isEditMode && {DESCRIPTON}} + + + + {isEditMode ? ( + + ) : ( +
{label}
+ )} +
+ ); + } +); +AntivirusRegistrationCard.displayName = 'AntivirusRegistrationCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/attack_surface_reduction_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/attack_surface_reduction_card.tsx new file mode 100644 index 0000000000000..c2356c248261b --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/attack_surface_reduction_card.tsx @@ -0,0 +1,95 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback } from 'react'; +import { OperatingSystem } from '@kbn/securitysolution-utils'; +import { EuiSwitch } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { cloneDeep } from 'lodash'; +import { useTestIdGenerator } from '../../../../../../hooks/use_test_id_generator'; +import { useLicense } from '../../../../../../../common/hooks/use_license'; +import { SettingLockedCard } from '../setting_locked_card'; +import type { PolicyFormComponentCommonProps } from '../../types'; +import { SettingCard } from '../setting_card'; + +const ATTACK_SURFACE_OS_LIST = [OperatingSystem.WINDOWS]; + +const LOCKED_CARD_ATTACK_SURFACE_REDUCTION = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.attack_surface_reduction', + { + defaultMessage: 'Attack Surface Reduction', + } +); + +const CARD_TITLE = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.attackSurfaceReduction.type', + { + defaultMessage: 'Attack surface reduction', + } +); + +const SWITCH_ENABLED_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.credentialHardening.toggleEnabled', + { + defaultMessage: 'Credential hardening enabled', + } +); + +const SWITCH_DISABLED_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.credentialHardening.toggleDisabled', + { + defaultMessage: 'Credential hardening disabled', + } +); + +type AttackSurfaceReductionCardProps = PolicyFormComponentCommonProps; + +export const AttackSurfaceReductionCard = memo( + ({ policy, onChange, mode, 'data-test-subj': dataTestSubj }) => { + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const getTestId = useTestIdGenerator(dataTestSubj); + const isChecked = policy.windows.attack_surface_reduction.credential_hardening.enabled; + const isEditMode = mode === 'edit'; + const label = isChecked ? SWITCH_ENABLED_LABEL : SWITCH_DISABLED_LABEL; + + const handleSwitchChange = useCallback( + (event) => { + const updatedPolicy = cloneDeep(policy); + + updatedPolicy.windows.attack_surface_reduction.credential_hardening.enabled = + event.target.checked; + + onChange({ isValid: true, updatedPolicy }); + }, + [onChange, policy] + ); + + if (!isPlatinumPlus) { + return ; + } + + return ( + + {isEditMode ? ( + + ) : ( + <>{label} + )} + + ); + } +); +AttackSurfaceReductionCard.displayName = 'AttackSurfaceReductionCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.tsx new file mode 100644 index 0000000000000..033fa855f6f5a --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/behaviour_protection_card.tsx @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { OperatingSystem } from '@kbn/securitysolution-utils'; +import { EuiCallOut, EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useTestIdGenerator } from '../../../../../../hooks/use_test_id_generator'; +import { SettingCard } from '../setting_card'; +import { NotifyUserOption } from '../notify_user_option'; +import { DetectPreventProtectionLevel } from '../detect_prevent_protection_level'; +import { ProtectionSettingCardSwitch } from '../protection_setting_card_switch'; +import type { Immutable } from '../../../../../../../../common/endpoint/types'; +import { PolicyOperatingSystem } from '../../../../../../../../common/endpoint/types'; +import type { BehaviorProtectionOSes } from '../../../../types'; +import { LinkToApp } from '../../../../../../../common/components/endpoint/link_to_app'; +import { APP_UI_ID, SecurityPageName } from '../../../../../../../../common'; +import { useLicense } from '../../../../../../../common/hooks/use_license'; +import { SettingLockedCard } from '../setting_locked_card'; +import type { PolicyFormComponentCommonProps } from '../../types'; + +const LOCKED_CARD_BEHAVIOR_TITLE = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.behavior', + { + defaultMessage: 'Malicious Behavior', + } +); + +const BEHAVIOUR_OS_VALUES: Immutable = [ + PolicyOperatingSystem.windows, + PolicyOperatingSystem.mac, + PolicyOperatingSystem.linux, +]; + +type BehaviourProtectionCardProps = PolicyFormComponentCommonProps; + +export const BehaviourProtectionCard = memo( + ({ policy, onChange, mode, 'data-test-subj': dataTestSubj }) => { + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const getTestId = useTestIdGenerator(dataTestSubj); + const protection = 'behavior_protection'; + const protectionLabel = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.behavior', + { + defaultMessage: 'Malicious behavior protections', + } + ); + + if (!isPlatinumPlus) { + return ; + } + + return ( + + } + > + + + + + + + + + + ), + }} + /> + + + ); + } +); +BehaviourProtectionCard.displayName = 'BehaviourProtectionCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/event_collection_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/event_collection_card.tsx new file mode 100644 index 0000000000000..0b59cf42c2307 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/event_collection_card.tsx @@ -0,0 +1,283 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ReactElement, ReactNode } from 'react'; +import React, { memo, useCallback, useContext, useMemo } from 'react'; +import { OperatingSystem } from '@kbn/securitysolution-utils'; +import { ThemeContext } from 'styled-components'; +import { i18n } from '@kbn/i18n'; +import { + EuiBetaBadge, + EuiCheckbox, + EuiFlexGroup, + EuiFlexItem, + EuiIconTip, + EuiSpacer, + EuiText, + useGeneratedHtmlId, +} from '@elastic/eui'; +import { cloneDeep, get, set } from 'lodash'; +import type { EuiCheckboxProps } from '@elastic/eui/src/components/form/checkbox/checkbox'; +import { getEmptyValue } from '../../../../../../../common/components/empty_value'; +import { useTestIdGenerator } from '../../../../../../hooks/use_test_id_generator'; +import type { PolicyFormComponentCommonProps } from '../../types'; +import { SettingCard, SettingCardHeader } from '../setting_card'; +import { PolicyOperatingSystem } from '../../../../../../../../common/endpoint/types'; +import type { UIPolicyConfig } from '../../../../../../../../common/endpoint/types'; + +const mapOperatingSystemToPolicyOsKey = { + [OperatingSystem.WINDOWS]: PolicyOperatingSystem.windows, + [OperatingSystem.LINUX]: PolicyOperatingSystem.linux, + [OperatingSystem.MAC]: PolicyOperatingSystem.mac, +} as const; + +type OperatingSystemToOsMap = typeof mapOperatingSystemToPolicyOsKey; + +export type ProtectionField = + keyof UIPolicyConfig[OperatingSystemToOsMap[T]]['events']; + +export type EventFormSelection = { [K in ProtectionField]: boolean }; + +export interface EventFormOption { + name: string; + protectionField: ProtectionField; +} + +export interface SupplementalEventFormOption { + id?: string; + title?: string; + description?: string; + name: string; + uncheckedName?: string; + protectionField: ProtectionField; + tooltipText?: string; + beta?: boolean; + indented?: boolean; + isDisabled?(policyConfig: UIPolicyConfig): boolean; +} + +export interface EventCollectionCardProps + extends PolicyFormComponentCommonProps { + os: T; + options: ReadonlyArray>; + selection: EventFormSelection; + supplementalOptions?: ReadonlyArray>; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type ANY = any; +interface EventCollectionCardComponent { + (props: EventCollectionCardProps, context?: ANY): ReactElement< + ANY, + ANY + > | null; + displayName?: string | undefined; +} + +// eslint-disable-next-line react/display-name +export const EventCollectionCard = memo( + ({ + policy, + onChange, + mode, + os, + options, + selection, + supplementalOptions, + 'data-test-subj': dataTestSubj, + }: EventCollectionCardProps) => { + const getTestId = useTestIdGenerator(dataTestSubj); + const isEditMode = mode === 'edit'; + const theme = useContext(ThemeContext); + const totalOptions = options.length; + const policyOs = mapOperatingSystemToPolicyOsKey[os]; + + const selectedCount: number = useMemo(() => { + const supplementalSelectionFields: string[] = supplementalOptions + ? supplementalOptions.map((value) => value.protectionField as string) + : []; + return Object.entries(selection).filter(([key, value]) => + !supplementalSelectionFields.includes(key) ? value : false + ).length; + }, [selection, supplementalOptions]); + + return ( + + {i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.eventCollectionsEnabled', + { + defaultMessage: '{selected} / {total} event collections enabled', + values: { + selected: selectedCount, + total: totalOptions, + }, + } + )} + + } + dataTestSubj={getTestId()} + > + + {i18n.translate('xpack.securitySolution.endpoint.policyDetailsConfig.eventingEvents', { + defaultMessage: 'Events', + })} + + + + {options.map(({ name, protectionField }) => { + const keyPath = `${policyOs}.events.${protectionField}`; + + return ( + + ); + })} + + {selectedCount === 0 && !isEditMode &&
{getEmptyValue()}
} + + {supplementalOptions && + supplementalOptions.map( + ({ + title, + description, + name, + uncheckedName, + protectionField, + tooltipText, + beta, + indented, + isDisabled, + }) => { + const keyPath = `${policyOs}.events.${protectionField}`; + const isChecked = get(policy, keyPath); + + if (!isEditMode && !isChecked) { + return null; + } + + return ( +
+ {title && ( + <> + + {title} + + )} + + {description && ( + <> + + + {description} + + + )} + + + + + + + + + {tooltipText && ( + + + + )} + + {beta && ( + + + + )} + +
+ ); + } + )} +
+ ); + } +) as EventCollectionCardComponent; +EventCollectionCard.displayName = 'EventCollectionCard'; + +interface EventCheckboxProps + extends PolicyFormComponentCommonProps, + Pick { + keyPath: string; + unCheckedLabel?: ReactNode; +} + +const EventCheckbox = memo( + ({ + policy, + onChange, + label, + unCheckedLabel, + mode, + keyPath, + disabled, + 'data-test-subj': dataTestSubj, + }) => { + const checkboxId = useGeneratedHtmlId(); + const isChecked: boolean = get(policy, keyPath); + const isEditMode = mode === 'edit'; + const displayLabel = isChecked ? label : unCheckedLabel ? unCheckedLabel : label; + + const checkboxOnChangeHandler = useCallback( + (ev) => { + const updatedPolicy = cloneDeep(policy); + set(updatedPolicy, keyPath, ev.target.checked); + + onChange({ isValid: true, updatedPolicy }); + }, + [keyPath, onChange, policy] + ); + + return isEditMode ? ( + + ) : isChecked ? ( +
{displayLabel}
+ ) : null; + } +); +EventCheckbox.displayName = 'EventCheckbox'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/linux.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/linux_event_collection_card.tsx similarity index 65% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/linux.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/linux_event_collection_card.tsx index f32f83cdf70cb..1bd1943718b29 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/linux.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/linux_event_collection_card.tsx @@ -5,16 +5,13 @@ * 2.0. */ -import React, { memo } from 'react'; -import { i18n } from '@kbn/i18n'; -import { useDispatch } from 'react-redux'; +import React, { memo, useMemo } from 'react'; import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { policyConfig } from '../../../store/policy_details/selectors'; -import { setIn } from '../../../models/policy_details_config'; -import { usePolicyDetailsSelector } from '../../policy_hooks'; -import type { EventFormOption, SupplementalEventFormOption } from '../../components/events_form'; -import { EventsForm } from '../../components/events_form'; -import type { UIPolicyConfig } from '../../../../../../../common/endpoint/types'; +import { i18n } from '@kbn/i18n'; +import type { PolicyFormComponentCommonProps } from '../../types'; +import type { UIPolicyConfig } from '../../../../../../../../common/endpoint/types'; +import type { EventFormOption, SupplementalEventFormOption } from './event_collection_card'; +import { EventCollectionCard } from './event_collection_card'; const OPTIONS: ReadonlyArray> = [ { @@ -45,6 +42,7 @@ const OPTIONS: ReadonlyArray> = [ const SUPPLEMENTAL_OPTIONS: ReadonlyArray> = [ { + id: 'sessionDataSection', title: i18n.translate( 'xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data.title', { @@ -59,11 +57,17 @@ const SUPPLEMENTAL_OPTIONS: ReadonlyArray { return !config.linux.events.process; @@ -71,11 +75,17 @@ const SUPPLEMENTAL_OPTIONS: ReadonlyArray { - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const dispatch = useDispatch(); +type LinuxEventCollectionCardProps = PolicyFormComponentCommonProps; + +export const LinuxEventCollectionCard = memo((props) => { + const supplementalOptions = useMemo(() => { + if (props.mode === 'edit') { + return SUPPLEMENTAL_OPTIONS; + } + + // View only mode: remove instructions for session data + return SUPPLEMENTAL_OPTIONS.map((option) => { + if (option.id === 'sessionDataSection') { + return { + ...option, + description: undefined, + }; + } + + return option; + }); + }, [props.mode]); return ( - + + {...props} os={OperatingSystem.LINUX} - selection={policyDetailsConfig.linux.events} + selection={props.policy.linux.events} + supplementalOptions={supplementalOptions} options={OPTIONS} - supplementalOptions={SUPPLEMENTAL_OPTIONS} - onValueSelection={(value, selected) => { - let newConfig = setIn(policyDetailsConfig)('linux')('events')(value)(selected); - - if (value === 'session_data' && !selected) { - newConfig = setIn(newConfig)('linux')('events')('tty_io')(false); - } - - dispatch({ - type: 'userChangedPolicyConfig', - payload: { - policyConfig: newConfig, - }, - }); - }} /> ); }); - -LinuxEvents.displayName = 'LinuxEvents'; +LinuxEventCollectionCard.displayName = 'LinuxEventCollectionCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/mac.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/mac_event_collection_card.tsx similarity index 55% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/mac.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/mac_event_collection_card.tsx index 7682a91daafcc..215722635c420 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/mac.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/mac_event_collection_card.tsx @@ -6,14 +6,11 @@ */ import React, { memo } from 'react'; -import { i18n } from '@kbn/i18n'; -import { useDispatch } from 'react-redux'; import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { policyConfig } from '../../../store/policy_details/selectors'; -import { setIn } from '../../../models/policy_details_config'; -import { usePolicyDetailsSelector } from '../../policy_hooks'; -import type { EventFormOption } from '../../components/events_form'; -import { EventsForm } from '../../components/events_form'; +import { i18n } from '@kbn/i18n'; +import type { EventFormOption } from './event_collection_card'; +import { EventCollectionCard } from './event_collection_card'; +import type { PolicyFormComponentCommonProps } from '../../types'; const OPTIONS: ReadonlyArray> = [ { @@ -36,23 +33,16 @@ const OPTIONS: ReadonlyArray> = [ }, ]; -export const MacEvents = memo(() => { - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const dispatch = useDispatch(); +type MacEventCollectionCardProps = PolicyFormComponentCommonProps; +export const MacEventCollectionCard = memo((props) => { return ( - + + {...props} os={OperatingSystem.MAC} - selection={policyDetailsConfig.mac.events} + selection={props.policy.mac.events} options={OPTIONS} - onValueSelection={(value, selected) => - dispatch({ - type: 'userChangedPolicyConfig', - payload: { policyConfig: setIn(policyDetailsConfig)('mac')('events')(value)(selected) }, - }) - } /> ); }); - -MacEvents.displayName = 'MacEvents'; +MacEventCollectionCard.displayName = 'MacEventCollectionCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/malware_protections_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/malware_protections_card.tsx new file mode 100644 index 0000000000000..74dbc65737f76 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/malware_protections_card.tsx @@ -0,0 +1,205 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiCallOut, + EuiSpacer, + EuiSwitch, + EuiFlexGroup, + EuiFlexItem, + EuiIconTip, +} from '@elastic/eui'; +import { OperatingSystem } from '@kbn/securitysolution-utils'; +import { cloneDeep } from 'lodash'; +import { NotifyUserOption } from '../notify_user_option'; +import { SettingCard } from '../setting_card'; +import type { PolicyFormComponentCommonProps } from '../../types'; +import { APP_UI_ID } from '../../../../../../../../common'; +import { SecurityPageName } from '../../../../../../../app/types'; +import type { Immutable } from '../../../../../../../../common/endpoint/types'; +import { PolicyOperatingSystem } from '../../../../../../../../common/endpoint/types'; +import type { MalwareProtectionOSes } from '../../../../types'; +import { LinkToApp } from '../../../../../../../common/components/endpoint/link_to_app'; +import type { ProtectionSettingCardSwitchProps } from '../protection_setting_card_switch'; +import { ProtectionSettingCardSwitch } from '../protection_setting_card_switch'; +import { DetectPreventProtectionLevel } from '../detect_prevent_protection_level'; +import { useTestIdGenerator } from '../../../../../../hooks/use_test_id_generator'; + +const BLOCKLIST_ENABLED_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.blocklistEnabled', + { + defaultMessage: 'Blocklist enabled', + } +); + +const BLOCKLIST_DISABLED_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.blocklistDisabled', + { + defaultMessage: 'Blocklist disabled', + } +); + +// NOTE: it mutates `policyConfigData` passed on input +const adjustBlocklistSettingsOnProtectionSwitch: ProtectionSettingCardSwitchProps['additionalOnSwitchChange'] = + ({ value, policyConfigData, protectionOsList }) => { + for (const os of protectionOsList) { + policyConfigData[os].malware.blocklist = value; + } + + return policyConfigData; + }; + +const MALWARE_OS_VALUES: Immutable = [ + PolicyOperatingSystem.windows, + PolicyOperatingSystem.mac, + PolicyOperatingSystem.linux, +]; + +export type MalwareProtectionsProps = PolicyFormComponentCommonProps; + +/** The Malware Protections form for policy details + * which will configure for all relevant OSes. + */ +export const MalwareProtectionsCard = React.memo( + ({ policy, onChange, mode = 'edit', 'data-test-subj': dataTestSubj }) => { + const getTestId = useTestIdGenerator(dataTestSubj); + const protection = 'malware'; + const protectionLabel = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.malware', + { + defaultMessage: 'Malware protections', + } + ); + + return ( + + } + > + + + + + + + + + + + + + ), + }} + /> + + + ); + } +); + +MalwareProtectionsCard.displayName = 'MalwareProtectionsCard'; + +type EnableDisableBlocklistProps = PolicyFormComponentCommonProps; + +const EnableDisableBlocklist = memo(({ policy, onChange, mode }) => { + const checked = policy.windows.malware.blocklist; + const isDisabled = policy.windows.malware.mode === 'off'; + const isEditMode = mode === 'edit'; + const label = checked ? BLOCKLIST_ENABLED_LABEL : BLOCKLIST_DISABLED_LABEL; + + const handleBlocklistSwitchChange = useCallback( + (event) => { + const value = event.target.checked; + const newPayload = cloneDeep(policy); + + adjustBlocklistSettingsOnProtectionSwitch({ + value, + policyConfigData: newPayload, + protectionOsList: MALWARE_OS_VALUES, + }); + + onChange({ isValid: true, updatedPolicy: newPayload }); + }, + [onChange, policy] + ); + + return ( + + + {isEditMode ? ( + + ) : ( + <>{label} + )} + + + + + + } + /> + + + ); +}); +EnableDisableBlocklist.displayName = 'EnableDisableBlocklist'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/memory_protection_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/memory_protection_card.tsx new file mode 100644 index 0000000000000..3af9a422fc1a6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/memory_protection_card.tsx @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { OperatingSystem } from '@kbn/securitysolution-utils'; +import { EuiCallOut, EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useTestIdGenerator } from '../../../../../../hooks/use_test_id_generator'; +import { NotifyUserOption } from '../notify_user_option'; +import { DetectPreventProtectionLevel } from '../detect_prevent_protection_level'; +import { ProtectionSettingCardSwitch } from '../protection_setting_card_switch'; +import { SettingLockedCard } from '../setting_locked_card'; +import type { Immutable } from '../../../../../../../../common/endpoint/types'; +import { PolicyOperatingSystem } from '../../../../../../../../common/endpoint/types'; +import type { MemoryProtectionOSes } from '../../../../types'; +import { LinkToApp } from '../../../../../../../common/components/endpoint/link_to_app'; +import { APP_UI_ID, SecurityPageName } from '../../../../../../../../common'; +import { useLicense } from '../../../../../../../common/hooks/use_license'; +import type { PolicyFormComponentCommonProps } from '../../types'; +import { SettingCard } from '../setting_card'; + +const LOCKED_CARD_MEMORY_TITLE = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.memory', + { + defaultMessage: 'Memory Threat', + } +); + +const MEMORY_PROTECTION_OS_VALUES: Immutable = [ + PolicyOperatingSystem.windows, + PolicyOperatingSystem.mac, + PolicyOperatingSystem.linux, +]; + +type MemoryProtectionCardProps = PolicyFormComponentCommonProps; + +export const MemoryProtectionCard = memo( + ({ policy, onChange, mode, 'data-test-subj': dataTestSubj }) => { + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const getTestId = useTestIdGenerator(dataTestSubj); + const protection = 'memory_protection'; + const protectionLabel = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.memory', + { + defaultMessage: 'Memory threat protections', + } + ); + + if (!isPlatinumPlus) { + return ; + } + + return ( + + } + > + + + + + + + + + + ), + }} + /> + + + ); + } +); +MemoryProtectionCard.displayName = 'MemoryProtectionCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/ransomware_protection_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/ransomware_protection_card.tsx new file mode 100644 index 0000000000000..b1988ab53c482 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/ransomware_protection_card.tsx @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { OperatingSystem } from '@kbn/securitysolution-utils'; +import { EuiCallOut, EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useTestIdGenerator } from '../../../../../../hooks/use_test_id_generator'; +import { ProtectionSettingCardSwitch } from '../protection_setting_card_switch'; +import { NotifyUserOption } from '../notify_user_option'; +import { DetectPreventProtectionLevel } from '../detect_prevent_protection_level'; +import { SettingCard } from '../setting_card'; +import type { PolicyFormComponentCommonProps } from '../../types'; +import type { Immutable } from '../../../../../../../../common/endpoint/types'; +import { PolicyOperatingSystem } from '../../../../../../../../common/endpoint/types'; +import type { RansomwareProtectionOSes } from '../../../../types'; +import { LinkToApp } from '../../../../../../../common/components/endpoint/link_to_app'; +import { APP_UI_ID, SecurityPageName } from '../../../../../../../../common'; +import { useLicense } from '../../../../../../../common/hooks/use_license'; +import { SettingLockedCard } from '../setting_locked_card'; + +const RANSOMEWARE_OS_VALUES: Immutable = [ + PolicyOperatingSystem.windows, +]; + +const LOCKED_CARD_RAMSOMWARE_TITLE = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.ransomware', + { + defaultMessage: 'Ransomware', + } +); + +type RansomwareProtectionCardProps = PolicyFormComponentCommonProps; + +export const RansomwareProtectionCard = React.memo( + ({ policy, onChange, mode, 'data-test-subj': dataTestSubj }) => { + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const getTestId = useTestIdGenerator(dataTestSubj); + const protection = 'ransomware'; + const protectionLabel = i18n.translate( + 'xpack.securitySolution.endpoint.policy.protections.ransomware', + { + defaultMessage: 'Ransomware protections', + } + ); + + if (!isPlatinumPlus) { + return ; + } + + return ( + + } + > + + + + + + + + + + ), + }} + /> + + + ); + } +); +RansomwareProtectionCard.displayName = 'RansomwareProtectionCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/windows.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/windows_event_collection_card.tsx similarity index 71% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/windows.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/windows_event_collection_card.tsx index 9ba51a819e041..33653e2f603a7 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/windows.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/cards/windows_event_collection_card.tsx @@ -7,13 +7,10 @@ import React, { memo } from 'react'; import { i18n } from '@kbn/i18n'; -import { useDispatch } from 'react-redux'; import { OperatingSystem } from '@kbn/securitysolution-utils'; -import { policyConfig } from '../../../store/policy_details/selectors'; -import { setIn } from '../../../models/policy_details_config'; -import { usePolicyDetailsSelector } from '../../policy_hooks'; -import type { EventFormOption } from '../../components/events_form'; -import { EventsForm } from '../../components/events_form'; +import type { EventFormOption } from './event_collection_card'; +import { EventCollectionCard } from './event_collection_card'; +import type { PolicyFormComponentCommonProps } from '../../types'; const OPTIONS: ReadonlyArray> = [ { @@ -87,25 +84,16 @@ const OPTIONS: ReadonlyArray> = [ }, ]; -export const WindowsEvents = memo(() => { - const policyDetailsConfig = usePolicyDetailsSelector(policyConfig); - const dispatch = useDispatch(); +type WindowsEventCollectionCardProps = PolicyFormComponentCommonProps; +export const WindowsEventCollectionCard = memo((props) => { return ( - + + {...props} os={OperatingSystem.WINDOWS} - selection={policyDetailsConfig.windows.events} + selection={props.policy.windows.events} options={OPTIONS} - onValueSelection={(value, selected) => - dispatch({ - type: 'userChangedPolicyConfig', - payload: { - policyConfig: setIn(policyDetailsConfig)('windows')('events')(value)(selected), - }, - }) - } /> ); }); - -WindowsEvents.displayName = 'WindowsEvents'; +WindowsEventCollectionCard.displayName = 'WindowsEventCollectionCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/detect_prevent_protection_level.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/detect_prevent_protection_level.tsx new file mode 100644 index 0000000000000..a141234ded60e --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/detect_prevent_protection_level.tsx @@ -0,0 +1,185 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo, useCallback, useMemo } from 'react'; +import { cloneDeep } from 'lodash'; +import type { EuiFlexItemProps } from '@elastic/eui'; +import { EuiRadio, EuiSpacer, EuiFlexGroup, EuiFlexItem, useGeneratedHtmlId } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useTestIdGenerator } from '../../../../../hooks/use_test_id_generator'; +import { SettingCardHeader } from './setting_card'; +import type { PolicyFormComponentCommonProps } from '../types'; +import type { + ImmutableArray, + UIPolicyConfig, + Immutable, +} from '../../../../../../../common/endpoint/types'; +import { ProtectionModes } from '../../../../../../../common/endpoint/types'; +import type { MacPolicyProtection, LinuxPolicyProtection, PolicyProtection } from '../../../types'; +import { useLicense } from '../../../../../../common/hooks/use_license'; + +const DETECT_LABEL = i18n.translate('xpack.securitySolution.endpoint.policy.details.detect', { + defaultMessage: 'Detect', +}); + +const PREVENT_LABEL = i18n.translate('xpack.securitySolution.endpoint.policy.details.prevent', { + defaultMessage: 'Prevent', +}); + +export type DetectPreventProtectionLavelProps = PolicyFormComponentCommonProps & { + protection: PolicyProtection; + osList: ImmutableArray>; +}; + +export const DetectPreventProtectionLevel = memo( + ({ policy, protection, osList, mode, onChange, 'data-test-subj': dataTestSubj }) => { + const isEditMode = mode === 'edit'; + const getTestId = useTestIdGenerator(dataTestSubj); + + const radios: Immutable< + Array<{ + id: ProtectionModes; + label: string; + flexGrow: EuiFlexItemProps['grow']; + }> + > = useMemo(() => { + return [ + { + id: ProtectionModes.detect, + label: DETECT_LABEL, + flexGrow: 1, + }, + { + id: ProtectionModes.prevent, + label: PREVENT_LABEL, + flexGrow: 5, + }, + ]; + }, []); + + const currentProtectionLevelLabel = useMemo(() => { + const radio = radios.find((item) => item.id === policy.windows[protection].mode); + + if (radio) { + return radio.label; + } + + return PREVENT_LABEL; + }, [policy.windows, protection, radios]); + + return ( +
+ + + + + + {isEditMode ? ( + radios.map(({ label, id, flexGrow }) => { + return ( + + + + ); + }) + ) : ( + <>{currentProtectionLevelLabel} + )} + +
+ ); + } +); +DetectPreventProtectionLevel.displayName = 'DetectPreventProtectionLevel'; + +interface ProtectionRadioProps extends PolicyFormComponentCommonProps { + protection: PolicyProtection; + protectionMode: ProtectionModes; + osList: ImmutableArray>; + label: string; +} + +const ProtectionRadio = React.memo( + ({ + protection, + protectionMode, + osList, + label, + onChange, + policy, + mode, + 'data-test-subj': dataTestSubj, + }: ProtectionRadioProps) => { + const radioButtonId = useGeneratedHtmlId(); + const selected = policy.windows[protection].mode; + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const showEditableFormFields = mode === 'edit'; + + const handleRadioChange = useCallback(() => { + const newPayload = cloneDeep(policy); + + for (const os of osList) { + if (os === 'windows') { + newPayload[os][protection].mode = protectionMode; + } else if (os === 'mac') { + newPayload[os][protection as MacPolicyProtection].mode = protectionMode; + } else if (os === 'linux') { + newPayload[os][protection as LinuxPolicyProtection].mode = protectionMode; + } + if (isPlatinumPlus) { + if (os === 'windows') { + if (protectionMode === ProtectionModes.prevent) { + newPayload[os].popup[protection].enabled = true; + } else { + newPayload[os].popup[protection].enabled = false; + } + } else if (os === 'mac') { + if (protectionMode === ProtectionModes.prevent) { + newPayload[os].popup[protection as MacPolicyProtection].enabled = true; + } else { + newPayload[os].popup[protection as MacPolicyProtection].enabled = false; + } + } else if (os === 'linux') { + if (protectionMode === ProtectionModes.prevent) { + newPayload[os].popup[protection as LinuxPolicyProtection].enabled = true; + } else { + newPayload[os].popup[protection as LinuxPolicyProtection].enabled = false; + } + } + } + } + + onChange({ isValid: true, updatedPolicy: newPayload }); + }, [isPlatinumPlus, onChange, osList, policy, protection, protectionMode]); + + return ( + + ); + } +); + +ProtectionRadio.displayName = 'ProtectionRadio'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/notify_user_option.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/notify_user_option.tsx new file mode 100644 index 0000000000000..f7afe7bd186d6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/notify_user_option.tsx @@ -0,0 +1,291 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { cloneDeep } from 'lodash'; +import { + EuiSpacer, + EuiFlexItem, + EuiFlexGroup, + EuiCheckbox, + EuiIconTip, + EuiText, + EuiTextArea, +} from '@elastic/eui'; +import { PROTECTION_NOTICE_SUPPORTED_ENDPOINT_VERSION } from '../protection_notice_supported_endpoint_version'; +import { useTestIdGenerator } from '../../../../../hooks/use_test_id_generator'; +import { getEmptyValue } from '../../../../../../common/components/empty_value'; +import { useLicense } from '../../../../../../common/hooks/use_license'; +import { SettingCardHeader } from './setting_card'; +import type { PolicyFormComponentCommonProps } from '../types'; +import type { ImmutableArray, UIPolicyConfig } from '../../../../../../../common/endpoint/types'; +import { ProtectionModes } from '../../../../../../../common/endpoint/types'; +import type { PolicyProtection, MacPolicyProtection, LinuxPolicyProtection } from '../../../types'; + +const NOTIFY_USER_CHECKBOX_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policyDetail.notifyUser', + { + defaultMessage: 'Notify user', + } +); + +const DO_NOT_NOTIFY_USER_CHECKBOX_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policyDetail.doNotNotifyUser', + { + defaultMessage: "Don't notify user", + } +); + +const NOTIFICATION_MESSAGE_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policyDetailsConfig.notificationMessage', + { + defaultMessage: 'Notification message', + } +); + +const CUSTOMIZE_NOTIFICATION_MESSAGE_LABEL = i18n.translate( + 'xpack.securitySolution.endpoint.policyDetailsConfig.customizeUserNotification', + { + defaultMessage: 'Customize notification message', + } +); + +interface NotifyUserOptionProps extends PolicyFormComponentCommonProps { + protection: PolicyProtection; + osList: ImmutableArray>; +} + +export const NotifyUserOption = React.memo( + ({ + policy, + onChange, + mode, + protection, + osList, + 'data-test-subj': dataTestSubj, + }: NotifyUserOptionProps) => { + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const getTestId = useTestIdGenerator(dataTestSubj); + + const isEditMode = mode === 'edit'; + const selected = policy.windows[protection].mode; + const userNotificationSelected = policy.windows.popup[protection].enabled; + const userNotificationMessage = policy.windows.popup[protection].message; + const checkboxLabel = userNotificationSelected + ? NOTIFY_USER_CHECKBOX_LABEL + : DO_NOT_NOTIFY_USER_CHECKBOX_LABEL; + + const handleUserNotificationCheckbox = useCallback( + (event) => { + const newPayload = cloneDeep(policy); + + for (const os of osList) { + if (os === 'windows') { + newPayload[os].popup[protection].enabled = event.target.checked; + } else if (os === 'mac') { + newPayload[os].popup[protection as MacPolicyProtection].enabled = event.target.checked; + } else if (os === 'linux') { + newPayload[os].popup[protection as LinuxPolicyProtection].enabled = + event.target.checked; + } + } + + onChange({ isValid: true, updatedPolicy: newPayload }); + }, + [policy, onChange, osList, protection] + ); + + const handleCustomUserNotification = useCallback( + (event) => { + const newPayload = cloneDeep(policy); + for (const os of osList) { + if (os === 'windows') { + newPayload[os].popup[protection].message = event.target.value; + } else if (os === 'mac') { + newPayload[os].popup[protection as MacPolicyProtection].message = event.target.value; + } else if (os === 'linux') { + newPayload[os].popup[protection as LinuxPolicyProtection].message = event.target.value; + } + } + + onChange({ isValid: true, updatedPolicy: newPayload }); + }, + [policy, onChange, osList, protection] + ); + + const tooltipProtectionText = useCallback((protectionType: PolicyProtection) => { + if (protectionType === 'memory_protection') { + return i18n.translate( + 'xpack.securitySolution.endpoint.policyDetail.memoryProtectionTooltip', + { + defaultMessage: 'memory threat', + } + ); + } else if (protectionType === 'behavior_protection') { + return i18n.translate( + 'xpack.securitySolution.endpoint.policyDetail.behaviorProtectionTooltip', + { + defaultMessage: 'malicious behavior', + } + ); + } else { + return protectionType; + } + }, []); + + const tooltipBracketText = useCallback( + (protectionType: PolicyProtection) => { + if (protectionType === 'memory_protection' || protection === 'behavior_protection') { + return i18n.translate('xpack.securitySolution.endpoint.policyDetail.rule', { + defaultMessage: 'rule', + }); + } else { + return i18n.translate('xpack.securitySolution.endpoint.policyDetail.filename', { + defaultMessage: 'filename', + }); + } + }, + [protection] + ); + + if (!isPlatinumPlus) { + return null; + } + + return ( +
+ + + + + + + + + + {isEditMode ? ( + + ) : ( + <>{checkboxLabel} + )} + + {userNotificationSelected && + (isEditMode ? ( + <> + + + + +

{CUSTOMIZE_NOTIFICATION_MESSAGE_LABEL}

+
+
+ + + + + + + } + /> + +
+ + + + ) : ( + <> + + +

{NOTIFICATION_MESSAGE_LABEL}

+
+ + <>{userNotificationMessage || getEmptyValue()} + + ))} +
+ ); + } +); +NotifyUserOption.displayName = 'NotifyUserOption'; + +export const SupportedVersionForProtectionNotice = React.memo( + ({ + protection, + 'data-test-subj': dataTestSubj, + }: { + protection: string; + 'data-test-subj'?: string; + }) => { + const version = useMemo(() => { + return PROTECTION_NOTICE_SUPPORTED_ENDPOINT_VERSION[ + protection as keyof typeof PROTECTION_NOTICE_SUPPORTED_ENDPOINT_VERSION + ]; + }, [protection]); + + if (!version) { + return null; + } + + return ( + + + + + + ); + } +); +SupportedVersionForProtectionNotice.displayName = 'SupportedVersionForProtectionNotice'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx new file mode 100644 index 0000000000000..cdd636b9c4baa --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/protection_setting_card_switch.tsx @@ -0,0 +1,140 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiSwitch } from '@elastic/eui'; +import { cloneDeep } from 'lodash'; +import type { PolicyFormComponentCommonProps } from '../types'; +import { useLicense } from '../../../../../../common/hooks/use_license'; +import type { + ImmutableArray, + UIPolicyConfig, + PolicyConfig, +} from '../../../../../../../common/endpoint/types'; +import { ProtectionModes } from '../../../../../../../common/endpoint/types'; +import type { PolicyProtection, MacPolicyProtection, LinuxPolicyProtection } from '../../../types'; + +export interface ProtectionSettingCardSwitchProps extends PolicyFormComponentCommonProps { + protection: PolicyProtection; + protectionLabel?: string; + osList: ImmutableArray>; + additionalOnSwitchChange?: ({ + value, + policyConfigData, + protectionOsList, + }: { + value: boolean; + policyConfigData: PolicyConfig; + protectionOsList: ImmutableArray>; + }) => PolicyConfig; +} + +export const ProtectionSettingCardSwitch = React.memo( + ({ + protection, + protectionLabel, + osList, + additionalOnSwitchChange, + onChange, + policy, + mode, + 'data-test-subj': dataTestSubj, + }: ProtectionSettingCardSwitchProps) => { + const isPlatinumPlus = useLicense().isPlatinumPlus(); + const isEditMode = mode === 'edit'; + const selected = policy && policy.windows[protection].mode; + const switchLabel = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.protectionsEnabled', + { + defaultMessage: '{protectionLabel} {mode, select, true {enabled} false {disabled}}', + values: { + protectionLabel, + mode: selected !== ProtectionModes.off, + }, + } + ); + + const handleSwitchChange = useCallback( + (event) => { + const newPayload = cloneDeep(policy); + + if (event.target.checked === false) { + for (const os of osList) { + if (os === 'windows') { + newPayload[os][protection].mode = ProtectionModes.off; + } else if (os === 'mac') { + newPayload[os][protection as MacPolicyProtection].mode = ProtectionModes.off; + } else if (os === 'linux') { + newPayload[os][protection as LinuxPolicyProtection].mode = ProtectionModes.off; + } + if (isPlatinumPlus) { + if (os === 'windows') { + newPayload[os].popup[protection].enabled = event.target.checked; + } else if (os === 'mac') { + newPayload[os].popup[protection as MacPolicyProtection].enabled = + event.target.checked; + } else if (os === 'linux') { + newPayload[os].popup[protection as LinuxPolicyProtection].enabled = + event.target.checked; + } + } + } + } else { + for (const os of osList) { + if (os === 'windows') { + newPayload[os][protection].mode = ProtectionModes.prevent; + } else if (os === 'mac') { + newPayload[os][protection as MacPolicyProtection].mode = ProtectionModes.prevent; + } else if (os === 'linux') { + newPayload[os][protection as LinuxPolicyProtection].mode = ProtectionModes.prevent; + } + if (isPlatinumPlus) { + if (os === 'windows') { + newPayload[os].popup[protection].enabled = event.target.checked; + } else if (os === 'mac') { + newPayload[os].popup[protection as MacPolicyProtection].enabled = + event.target.checked; + } else if (os === 'linux') { + newPayload[os].popup[protection as LinuxPolicyProtection].enabled = + event.target.checked; + } + } + } + } + + onChange({ + isValid: true, + updatedPolicy: additionalOnSwitchChange + ? additionalOnSwitchChange({ + value: event.target.checked, + policyConfigData: newPayload, + protectionOsList: osList, + }) + : newPayload, + }); + }, + [policy, onChange, additionalOnSwitchChange, osList, isPlatinumPlus, protection] + ); + + if (!isEditMode) { + return <>{switchLabel}; + } + + return ( + + ); + } +); + +ProtectionSettingCardSwitch.displayName = 'ProtectionSettingCardSwitch'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/config_form/index.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/setting_card.tsx similarity index 77% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/components/config_form/index.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/setting_card.tsx index b5f46c91dade4..ebae19d960b69 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/components/config_form/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/setting_card.tsx @@ -23,6 +23,7 @@ import { import { ThemeContext } from 'styled-components'; import type { OperatingSystem } from '@kbn/securitysolution-utils'; +import { useTestIdGenerator } from '../../../../../hooks/use_test_id_generator'; import { OS_TITLES } from '../../../../../common/translations'; const TITLES = { @@ -34,7 +35,7 @@ const TITLES = { }), }; -interface ConfigFormProps { +interface SettingCardProps { /** * A subtitle for this component. **/ @@ -49,19 +50,22 @@ interface ConfigFormProps { rightCorner?: ReactNode; } -export const ConfigFormHeading: FC = memo(({ children }) => ( - -
{children}
-
-)); - -ConfigFormHeading.displayName = 'ConfigFormHeading'; +export const SettingCardHeader = memo<{ children: React.ReactNode; 'data-test-subj'?: string }>( + ({ children, 'data-test-subj': dataTestSubj }) => ( + +
{children}
+
+ ) +); +SettingCardHeader.displayName = 'SettingCardHeader'; -export const ConfigForm: FC = memo( +export const SettingCard: FC = memo( ({ type, supportedOss, osRestriction, dataTestSubj, rightCorner, children }) => { const paddingSize = useContext(ThemeContext).eui.euiPanelPaddingModifiers.paddingMedium; + const getTestId = useTestIdGenerator(dataTestSubj); + return ( - + = memo( style={{ padding: `${paddingSize} ${paddingSize} 0 ${paddingSize}` }} > - {TITLES.type} + {TITLES.type} {type} - {TITLES.os} + {TITLES.os} - {supportedOss.map((os) => OS_TITLES[os]).join(', ')} + + {supportedOss.map((os) => OS_TITLES[os]).join(', ')}{' '} + {osRestriction && ( @@ -117,4 +123,4 @@ export const ConfigForm: FC = memo( } ); -ConfigForm.displayName = 'ConfigForm'; +SettingCard.displayName = 'SettingCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/setting_locked_card.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/setting_locked_card.tsx new file mode 100644 index 0000000000000..bb2faa6f8abe2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/components/setting_locked_card.tsx @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { + EuiCard, + EuiIcon, + EuiTextColor, + EuiLink, + EuiFlexGroup, + EuiFlexItem, + EuiText, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import styled from 'styled-components'; +import { i18n } from '@kbn/i18n'; +import { useTestIdGenerator } from '../../../../../hooks/use_test_id_generator'; + +const LockedPolicyDiv = styled.div` + .euiCard__betaBadgeWrapper { + .euiCard__betaBadge { + width: auto; + } + } + .lockedCardDescription { + padding: 0 33.3%; + } +`; + +export const SettingLockedCard = memo( + ({ title, 'data-test-subj': dataTestSubj }: { title: string; 'data-test-subj'?: string }) => { + const getTestId = useTestIdGenerator(dataTestSubj); + + return ( + + } + title={ +

+ {title} +

+ } + description={false} + > + + + +

+ + + +

+
+ +

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

+
+
+
+
+
+ ); + } +); +SettingLockedCard.displayName = 'SettingLockedCard'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/index.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/index.ts similarity index 80% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/index.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/index.ts index cf989e6b4e0ee..b84c32fbeee97 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { PolicyFormLayout } from './policy_form_layout'; +export { PolicySettingsForm } from './policy_settings_form'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/mocks.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/mocks.ts new file mode 100644 index 0000000000000..c351bea4fdf93 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/mocks.ts @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +interface TestSubjGenerator { + (suffix?: string): string; + withPrefix: (prefix: string) => TestSubjGenerator; +} + +export const createTestSubjGenerator = (testSubjPrefix: string): TestSubjGenerator => { + const testSubjGenerator: TestSubjGenerator = (suffix) => { + if (suffix) { + return `${testSubjPrefix}-${suffix}`; + } + return testSubjPrefix; + }; + + testSubjGenerator.withPrefix = (prefix: string): TestSubjGenerator => { + return createTestSubjGenerator(testSubjGenerator(prefix)); + }; + + return testSubjGenerator; +}; + +export const getPolicySettingsFormTestSubjects = ( + formTopLevelTestSubj: string = 'endpointPolicyForm' +) => { + const genTestSubj = createTestSubjGenerator(formTopLevelTestSubj); + const malwareTestSubj = genTestSubj.withPrefix('malware'); + const ransomwareTestSubj = genTestSubj.withPrefix('ransomware'); + const memoryTestSubj = genTestSubj.withPrefix('memory'); + const behaviourTestSubj = genTestSubj.withPrefix('behaviour'); + const advancedSectionTestSubj = genTestSubj.withPrefix('advancedSection'); + const windowsEventsTestSubj = genTestSubj.withPrefix('windowsEvents'); + const macEventsTestSubj = genTestSubj.withPrefix('macEvents'); + const linuxEventsTestSubj = genTestSubj.withPrefix('linuxEvents'); + + const testSubj = { + form: genTestSubj(), + + malware: { + card: malwareTestSubj(), + enableDisableSwitch: malwareTestSubj('enableDisableSwitch'), + protectionPreventRadio: malwareTestSubj('protectionLevel-preventRadio'), + protectionDetectRadio: malwareTestSubj('protectionLevel-detectRadio'), + notifyUserCheckbox: malwareTestSubj('notifyUser-checkbox'), + notifySupportedVersion: malwareTestSubj('notifyUser-supportedVersion'), + notifyCustomMessage: malwareTestSubj('notifyUser-customMessage'), + notifyCustomMessageTooltipIcon: malwareTestSubj('notifyUser-tooltipIcon'), + notifyCustomMessageTooltipInfo: malwareTestSubj('notifyUser-tooltipInfo'), + osValuesContainer: malwareTestSubj('osValues'), + }, + ransomware: { + card: ransomwareTestSubj(), + enableDisableSwitch: ransomwareTestSubj('enableDisableSwitch'), + protectionPreventRadio: ransomwareTestSubj('protectionLevel-preventRadio'), + protectionDetectRadio: ransomwareTestSubj('protectionLevel-detectRadio'), + notifyUserCheckbox: ransomwareTestSubj('notifyUser-checkbox'), + notifySupportedVersion: ransomwareTestSubj('notifyUser-supportedVersion'), + notifyCustomMessage: ransomwareTestSubj('notifyUser-customMessage'), + notifyCustomMessageTooltipIcon: ransomwareTestSubj('notifyUser-tooltipIcon'), + notifyCustomMessageTooltipInfo: ransomwareTestSubj('notifyUser-tooltipInfo'), + osValuesContainer: ransomwareTestSubj('osValues'), + }, + memory: { + card: memoryTestSubj(), + enableDisableSwitch: memoryTestSubj('enableDisableSwitch'), + protectionPreventRadio: memoryTestSubj('protectionLevel-preventRadio'), + protectionDetectRadio: memoryTestSubj('protectionLevel-detectRadio'), + notifyUserCheckbox: memoryTestSubj('notifyUser-checkbox'), + osValuesContainer: memoryTestSubj('osValues'), + }, + behaviour: { + card: behaviourTestSubj(), + enableDisableSwitch: behaviourTestSubj('enableDisableSwitch'), + protectionPreventRadio: behaviourTestSubj('protectionLevel-preventRadio'), + protectionDetectRadio: behaviourTestSubj('protectionLevel-detectRadio'), + notifyUserCheckbox: behaviourTestSubj('notifyUser-checkbox'), + osValuesContainer: behaviourTestSubj('osValues'), + }, + attachSurface: { + card: genTestSubj('attackSurface'), + enableDisableSwitch: genTestSubj('attachSurface-enableDisableSwitch'), + osValuesContainer: genTestSubj('attackSurface-osValues'), + }, + + windowsEvents: { + card: windowsEventsTestSubj(), + dnsCheckbox: windowsEventsTestSubj('dns'), + processCheckbox: windowsEventsTestSubj('process'), + fileCheckbox: windowsEventsTestSubj('file'), + }, + macEvents: { + card: macEventsTestSubj(), + fileCheckbox: macEventsTestSubj('file'), + }, + linuxEvents: { + card: linuxEventsTestSubj(), + fileCheckbox: linuxEventsTestSubj('file'), + }, + antivirusRegistration: { + card: genTestSubj('antivirusRegistration'), + }, + advancedSection: { + container: advancedSectionTestSubj(''), + showHideButton: advancedSectionTestSubj('showButton'), + settingsContainer: advancedSectionTestSubj('settings'), + warningCallout: advancedSectionTestSubj('warning'), + }, + }; + + return testSubj; +}; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx new file mode 100644 index 0000000000000..8771e40e4be7c --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/policy_settings_form.tsx @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { EuiSpacer, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { AntivirusRegistrationCard } from './components/cards/antivirus_registration_card'; +import { LinuxEventCollectionCard } from './components/cards/linux_event_collection_card'; +import { MacEventCollectionCard } from './components/cards/mac_event_collection_card'; +import { WindowsEventCollectionCard } from './components/cards/windows_event_collection_card'; +import { AttackSurfaceReductionCard } from './components/cards/attack_surface_reduction_card'; +import { BehaviourProtectionCard } from './components/cards/behaviour_protection_card'; +import { MemoryProtectionCard } from './components/cards/memory_protection_card'; +import { RansomwareProtectionCard } from './components/cards/ransomware_protection_card'; +import { MalwareProtectionsCard } from './components/cards/malware_protections_card'; +import type { PolicyFormComponentCommonProps } from './types'; +import { AdvancedSection } from './components/advanced_section'; +import { useTestIdGenerator } from '../../../../hooks/use_test_id_generator'; + +const PROTECTIONS_SECTION_TITLE = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.protections', + { defaultMessage: 'Protections' } +); + +const SETTINGS_SECTION_TITLE = i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.settings', + { defaultMessage: 'Settings' } +); + +export type PolicySettingsFormProps = PolicyFormComponentCommonProps; + +export const PolicySettingsForm = memo((props) => { + const getTestId = useTestIdGenerator(props['data-test-subj']); + + return ( +
+ {PROTECTIONS_SECTION_TITLE} + + + + + + + + + + + + + + + + + + {SETTINGS_SECTION_TITLE} + + + + + + + + + + + + + + + +
+ ); +}); +PolicySettingsForm.displayName = 'PolicySettingsForm'; + +const FormSectionTitle = memo(({ children }) => { + return ( + +

{children}

+
+ ); +}); +FormSectionTitle.displayName = 'FormSectionTitle'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/protection_notice_supported_endpoint_version.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/protection_notice_supported_endpoint_version.ts new file mode 100644 index 0000000000000..5e518cb6215a6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/protection_notice_supported_endpoint_version.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const PROTECTION_NOTICE_SUPPORTED_ENDPOINT_VERSION = Object.freeze({ + malware: '7.11+', + ransomware: '7.12+', + memory_protection: '7.15+', + behavior_protection: '7.15+', +}); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/types.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/types.ts new file mode 100644 index 0000000000000..d09f8005750ee --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_form/types.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PolicyConfig } from '../../../../../../common/endpoint/types'; + +export interface PolicyFormComponentCommonProps { + policy: PolicyConfig; + onChange: (options: { isValid: boolean; updatedPolicy: PolicyConfig }) => void; + mode: 'edit' | 'view'; + 'data-test-subj'?: string; +} diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_confirm_update.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/components/policy_form_confirm_update.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_confirm_update.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/components/policy_form_confirm_update.tsx diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/index.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/index.ts similarity index 68% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/index.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/index.ts index 53f02b8e5349e..34ce6db6a0bb2 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/index.ts @@ -5,6 +5,4 @@ * 2.0. */ -export { WindowsEvents } from './windows'; -export { MacEvents } from './mac'; -export { LinuxEvents } from './linux'; +export { PolicySettingsLayout } from './policy_settings_layout'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/policy_settings_layout.tsx similarity index 51% rename from x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx rename to x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/policy_settings_layout.tsx index 34defb5b25ce6..bd7ecc6529c65 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/policy_settings_layout.tsx @@ -5,64 +5,58 @@ * 2.0. */ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiButton, - EuiButtonEmpty, - EuiLoadingSpinner, - EuiSpacer, -} from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; -import { useDispatch } from 'react-redux'; +import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { useLocation } from 'react-router-dom'; -import type { ApplicationStart } from '@kbn/core/public'; -import { toMountPoint } from '@kbn/kibana-react-plugin/public'; +import type { ApplicationStart } from '@kbn/core-application-browser'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiButton, EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; -import { useShowEditableFormFields, usePolicyDetailsSelector } from '../../policy_hooks'; -import { - policyDetails, - agentStatusSummary, - updateStatus, - isLoading, -} from '../../../store/policy_details/selectors'; - -import { useToasts, useKibana } from '../../../../../../common/lib/kibana'; -import type { AppAction } from '../../../../../../common/store/actions'; -import { getPoliciesPath } from '../../../../../common/routing'; -import { useNavigateToAppEventHandler } from '../../../../../../common/hooks/endpoint/use_navigate_to_app_event_handler'; -import { APP_UI_ID } from '../../../../../../../common/constants'; -import type { PolicyDetailsRouteState } from '../../../../../../../common/endpoint/types'; -import { SecuritySolutionPageWrapper } from '../../../../../../common/components/page_wrapper'; -import { PolicyDetailsForm } from '../../policy_details_form'; -import { ConfirmUpdate } from './policy_form_confirm_update'; - -export const PolicyFormLayout = React.memo(() => { - const dispatch = useDispatch<(action: AppAction) => void>(); +import { cloneDeep } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { useUserPrivileges } from '../../../../../common/components/user_privileges'; +import { useFetchAgentByAgentPolicySummary } from '../../../../hooks/policy/use_fetch_endpoint_policy_agent_summary'; +import { useUpdateEndpointPolicy } from '../../../../hooks/policy/use_update_endpoint_policy'; +import type { PolicySettingsFormProps } from '../policy_settings_form/policy_settings_form'; +import { PolicySettingsForm } from '../policy_settings_form'; +import type { + MaybeImmutable, + PolicyConfig, + PolicyData, + PolicyDetailsRouteState, +} from '../../../../../../common/endpoint/types'; +import { useKibana, useToasts } from '../../../../../common/lib/kibana'; +import { APP_UI_ID } from '../../../../../../common'; +import { getPoliciesPath } from '../../../../common/routing'; +import { useNavigateToAppEventHandler } from '../../../../../common/hooks/endpoint/use_navigate_to_app_event_handler'; +import { ConfirmUpdate } from './components/policy_form_confirm_update'; + +export interface PolicySettingsLayoutProps { + policy: MaybeImmutable; +} + +export const PolicySettingsLayout = memo(({ policy: _policy }) => { + const policy = _policy as PolicyData; const { services: { - theme, application: { navigateToApp }, }, } = useKibana(); const toasts = useToasts(); const { state: locationRouteState } = useLocation(); - const showEditableFormFields = useShowEditableFormFields(); - - // Store values - const policyItem = usePolicyDetailsSelector(policyDetails); - const policyAgentStatusSummary = usePolicyDetailsSelector(agentStatusSummary); - const policyUpdateStatus = usePolicyDetailsSelector(updateStatus); - const isPolicyLoading = usePolicyDetailsSelector(isLoading); + const { canWritePolicyManagement } = useUserPrivileges().endpointPrivileges; + const { isLoading: isUpdating, mutateAsync: sendPolicyUpdate } = useUpdateEndpointPolicy(); + const { data: agentSummaryData } = useFetchAgentByAgentPolicySummary(policy.policy_id); - // Local state + const [policySettings, setPolicySettings] = useState( + cloneDeep(policy.inputs[0].config.policy.value) + ); const [showConfirm, setShowConfirm] = useState(false); const [routeState, setRouteState] = useState(); - const policyName = policyItem?.name ?? ''; + const isEditMode = canWritePolicyManagement; + const policyName = policy?.name ?? ''; const routingOnCancelNavigateTo = routeState?.onCancelNavigateTo; + const navigateToAppArguments = useMemo((): Parameters => { if (routingOnCancelNavigateTo) { return routingOnCancelNavigateTo; @@ -76,60 +70,68 @@ export const PolicyFormLayout = React.memo(() => { ]; }, [routingOnCancelNavigateTo]); - // Handle showing update statuses - useEffect(() => { - if (policyUpdateStatus) { - if (policyUpdateStatus.success) { + const handleSettingsOnChange: PolicySettingsFormProps['onChange'] = useCallback((updates) => { + setPolicySettings(updates.updatedPolicy); + }, []); + + const handleCancelOnClick = useNavigateToAppEventHandler(...navigateToAppArguments); + + const handleSaveOnClick = useCallback(() => { + setShowConfirm(true); + }, []); + + const handleSaveCancel = useCallback(() => { + setShowConfirm(false); + }, []); + + const handleSaveConfirmation = useCallback(() => { + const update = cloneDeep(policy); + + update.inputs[0].config.policy.value = policySettings; + sendPolicyUpdate({ policy: update }) + .then(() => { toasts.addSuccess({ + 'data-test-subj': 'policyDetailsSuccessMessage', title: i18n.translate( 'xpack.securitySolution.endpoint.policy.details.updateSuccessTitle', { defaultMessage: 'Success!', } ), - text: toMountPoint( - - - , - { theme$: theme.theme$ } + text: i18n.translate( + 'xpack.securitySolution.endpoint.policy.details.updateSuccessMessage', + { + defaultMessage: 'Integration {name} has been updated.', + values: { name: policyName }, + } ), }); if (routeState && routeState.onSaveNavigateTo) { navigateToApp(...routeState.onSaveNavigateTo); } - } else { + }) + .catch((err) => { toasts.addDanger({ + 'data-test-subj': 'policyDetailsFailureMessage', title: i18n.translate('xpack.securitySolution.endpoint.policy.details.updateErrorTitle', { defaultMessage: 'Failed!', }), - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - text: policyUpdateStatus.error!.message, + text: err.message, }); - } - } - }, [navigateToApp, toasts, policyName, policyUpdateStatus, routeState, theme.theme$]); - - const handleCancelOnClick = useNavigateToAppEventHandler(...navigateToAppArguments); - - const handleSaveOnClick = useCallback(() => { - setShowConfirm(true); - }, []); - - const handleSaveConfirmation = useCallback(() => { - dispatch({ - type: 'userClickedPolicyDetailsSaveButton', - }); - setShowConfirm(false); - }, [dispatch]); - - const handleSaveCancel = useCallback(() => { - setShowConfirm(false); - }, []); + }); + + handleSaveCancel(); + }, [ + handleSaveCancel, + navigateToApp, + policy, + policyName, + policySettings, + routeState, + sendPolicyUpdate, + toasts, + ]); useEffect(() => { if (!routeState && locationRouteState) { @@ -137,28 +139,25 @@ export const PolicyFormLayout = React.memo(() => { } }, [locationRouteState, routeState]); - // Before proceeding - check if we have a policy data. - // If not, and we are still loading, show spinner. - // Else, if we have an error, then show error on the page. - if (!policyItem) { - return ( - - {isPolicyLoading ? : null} - - ); - } - return ( <> {showConfirm && ( )} - + + + + @@ -173,14 +172,14 @@ export const PolicyFormLayout = React.memo(() => { /> - {showEditableFormFields && ( + {isEditMode && ( { ); }); - -PolicyFormLayout.displayName = 'PolicyFormLayout'; +PolicySettingsLayout.displayName = 'PolicySettingsLayout'; diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx index e16d5fcb392a8..d3f9edc202acc 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/tabs/policy_tabs.tsx @@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import React, { useCallback, useEffect, useMemo } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; +import { PolicySettingsLayout } from '../policy_settings_layout'; import { useUserPrivileges } from '../../../../../common/components/user_privileges'; import { getPolicyDetailPath, @@ -36,7 +37,6 @@ import { policyIdFromParams, } from '../../store/policy_details/selectors'; import { PolicyArtifactsLayout } from '../artifacts/layout/policy_artifacts_layout'; -import { PolicyFormLayout } from '../policy_forms/components'; import { usePolicyDetailsSelector } from '../policy_hooks'; import { POLICY_ARTIFACT_EVENT_FILTERS_LABELS } from './event_filters_translations'; import { POLICY_ARTIFACT_TRUSTED_APPS_LABELS } from './trusted_apps_translations'; @@ -77,7 +77,11 @@ export const PolicyTabs = React.memo(() => { const isInHostIsolationExceptionsTab = usePolicyDetailsSelector(isOnHostIsolationExceptionsView); const isInBlocklistsTab = usePolicyDetailsSelector(isOnBlocklistsView); const policyId = usePolicyDetailsSelector(policyIdFromParams); - const policyItem = usePolicyDetailsSelector(policyDetails); + + // By the time the tabs load, we know that we already have a `policyItem` since a conditional + // check is done at the `PageDetails` component level. So asserting to non-null/undefined here. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const policyItem = usePolicyDetailsSelector(policyDetails)!; const { canReadTrustedApplications, canWriteTrustedApplications, @@ -195,7 +199,8 @@ export const PolicyTabs = React.memo(() => { content: ( <> - + + ), }, diff --git a/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts b/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts index a979d79db5663..0c6f4e7db9b89 100644 --- a/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts +++ b/x-pack/plugins/security_solution/public/management/services/policies/hooks.ts @@ -15,6 +15,7 @@ import type { GetPolicyListResponse } from '../../pages/policy/types'; import { sendGetEndpointSpecificPackagePolicies } from './policies'; import type { ServerApiError } from '../../../common/types'; +// FIXME:PT move to `hooks` folder export function useGetEndpointSpecificPolicies( { onError, diff --git a/x-pack/plugins/security_solution/public/management/services/policies/ingest.ts b/x-pack/plugins/security_solution/public/management/services/policies/ingest.ts index c6240c934ec8f..e5347449d4dbe 100644 --- a/x-pack/plugins/security_solution/public/management/services/policies/ingest.ts +++ b/x-pack/plugins/security_solution/public/management/services/policies/ingest.ts @@ -8,8 +8,6 @@ import type { HttpFetchOptions, HttpStart } from '@kbn/core/public'; import type { GetAgentStatusResponse, - GetAgentPoliciesRequest, - GetAgentPoliciesResponse, GetPackagePoliciesResponse, GetInfoResponse, } from '@kbn/fleet-plugin/common'; @@ -59,38 +57,6 @@ export const sendBulkGetPackagePolicies = ( }); }; -/** - * Retrieve a list of Agent Policies - * @param http - * @param options - */ -export const sendGetAgentPolicyList = ( - http: HttpStart, - options: HttpFetchOptions & GetAgentPoliciesRequest -) => { - return http.get(INGEST_API_AGENT_POLICIES, options); -}; - -/** - * Retrieve a list of Agent Policies - * @param http - * @param options - */ -export const sendBulkGetAgentPolicyList = ( - http: HttpStart, - ids: string[], - options: HttpFetchOptions = {} -) => { - return http.post(`${INGEST_API_AGENT_POLICIES}/_bulk_get`, { - ...options, - body: JSON.stringify({ - ids, - ignoreMissing: true, - full: true, - }), - }); -}; - /** * Updates a package policy * diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index dce1d4c5a02a2..abeb8e76b2f8a 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -28955,7 +28955,6 @@ "xpack.securitySolution.endpoint.list.totalCount": "Affichage de {totalItemCount, plural, one {# point de terminaison} many {# points de terminaison} other {# points de terminaison}}", "xpack.securitySolution.endpoint.list.totalCount.limited": "Affichage de {limit} sur {totalItemCount, plural, one {# point de terminaison} many {# points de terminaison} other {# points de terminaison}}", "xpack.securitySolution.endpoint.list.transformFailed.message": "Une transformation requise, {transformId}, est actuellement en échec. La plupart du temps, ce problème peut être corrigé par {transformsPage}. Pour une assistance supplémentaire, veuillez visitez la {docsPage}", - "xpack.securitySolution.endpoint.policy.advanced.show": "Paramètres avancés pour {action}", "xpack.securitySolution.endpoint.policy.artifacts.empty.unassigned.backButtonLabel": "Retour à la politique {policyName}", "xpack.securitySolution.endpoint.policy.artifacts.empty.unassigned.content": "Aucun artefact n'est actuellement affecté à {policyName}. Affectez des artefacts maintenant, ou ajoutez-les et gérez-les sur la page des artefacts.", "xpack.securitySolution.endpoint.policy.artifacts.empty.unassigned.noPrivileges.content": "Aucun artefact n'est actuellement affecté à {policyName}.", @@ -31590,7 +31589,6 @@ "xpack.securitySolution.endpoint.policy.blocklist.list.search.placeholder": "Rechercher sur les champs ci-dessous : nom, description, valeur", "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.explanation": "Activez la bascule pour enregistrer Elastic comme solution d'antivirus officielle pour le système d'exploitation Windows. Cela désactivera également Windows Defender.", "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.osRestriction": "Restrictions", - "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.toggle": "Enregistrer comme antivirus", "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.type": "Enregistrer comme antivirus", "xpack.securitySolution.endpoint.policy.details.attack_surface_reduction": "Réduction de la surface d’attaque", "xpack.securitySolution.endpoint.policy.details.attackSurfaceReduction.type": "Réduction de la surface d’attaque", @@ -31600,7 +31598,6 @@ "xpack.securitySolution.endpoint.policy.details.behavior_protection": "Comportement malveillant", "xpack.securitySolution.endpoint.policy.details.cancel": "Annuler", "xpack.securitySolution.endpoint.policy.details.cloudDeploymentLInk": "déploiement sur le cloud", - "xpack.securitySolution.endpoint.policy.details.credentialHardening.toggle": "Renforcement de l’identification", "xpack.securitySolution.endpoint.policy.details.detect": "Détecter", "xpack.securitySolution.endpoint.policy.details.detectionRulesLink": "règles de détection associées", "xpack.securitySolution.endpoint.policy.details.eventCollection": "Collection d'événements", @@ -31668,7 +31665,6 @@ "xpack.securitySolution.endpoint.policy.multiStepOnboarding.learnMore": "En savoir plus", "xpack.securitySolution.endpoint.policy.multiStepOnboarding.title": "Nous enregistrerons votre intégration avec nos valeurs par défaut recommandées.", "xpack.securitySolution.endpoint.policy.protections.behavior": "Protections contre les comportements malveillants", - "xpack.securitySolution.endpoint.policy.protections.blocklist": "Liste noire activée", "xpack.securitySolution.endpoint.policy.protections.malware": "Protections contre les malware", "xpack.securitySolution.endpoint.policy.protections.memory": "Protections de la mémoire contre les menaces", "xpack.securitySolution.endpoint.policy.protections.ransomware": "Protections contre les ransomware", @@ -31701,7 +31697,6 @@ "xpack.securitySolution.endpoint.policyDetails.agentsSummary.onlineTitle": "Intègre", "xpack.securitySolution.endpoint.policyDetails.agentsSummary.totalTitle": "Total des agents", "xpack.securitySolution.endpoint.policyDetails.artifacts.title": "Artefacts", - "xpack.securitySolution.endpoint.policyDetails.loadError": "Impossible de charger les paramètres de la politique des points de terminaison", "xpack.securitySolution.endpoint.policyDetails.settings.title": "Paramètres de politique", "xpack.securitySolution.endpoint.policyDetails.userNotification.placeholder": "Saisir votre message de notification personnalisé", "xpack.securitySolution.endpoint.policyDetailsConfig.blocklistTooltip": "Active ou désactive la liste noire associée à cette politique. La liste noire est une collection de hachages, de chemins ou de signataires qui étend la liste de processus considérés comme malveillants par le point de terminaison. Consultez l'onglet de la liste noire pour plus de détails sur l'entrée.", @@ -31710,10 +31705,8 @@ "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.file": "Fichier", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.network": "Réseau", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.process": "Processus", - "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data": "Collecter les données de session", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data.description": "Activez cette option pour capturer les données de processus étendues requises pour la vue de session. La vue de session vous fournit une représentation visuelle des données de session et d'exécution du processus. Les données de la vue de session sont organisées en fonction du modèle de processus Linux pour vous aider à examiner l'activité des processus, des utilisateurs et des services dans votre infrastructure Linux.", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data.title": "Données de session", - "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.tty_io": "Capturer la sortie du terminal", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.tty_io.tooltip": "Activez cette option pour collecter la sortie du terminal (tty). La sortie du terminal apparaît dans la vue de session, et vous pouvez l'afficher séparément pour voir quelles commandes ont été exécutées et comment elles ont été tapées, à condition que le terminal soit en mode écho. Fonctionne uniquement sur les hôtes qui prennent en charge ebpf.", "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.file": "Fichier", "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.network": "Réseau", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index a17cd63a4c62c..b996b954c9af4 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -28940,7 +28940,6 @@ "xpack.securitySolution.endpoint.list.totalCount": "{totalItemCount, plural, other {#個のエンドポイント}}を表示中", "xpack.securitySolution.endpoint.list.totalCount.limited": "{limit}/{totalItemCount, plural, other {#個のエンドポイント}}ページを表示中", "xpack.securitySolution.endpoint.list.transformFailed.message": "現在、必須のトランスフォーム{transformId}が失敗しています。通常、これは{transformsPage}で修正できます。ヘルプについては、{docsPage}ご覧ください", - "xpack.securitySolution.endpoint.policy.advanced.show": "{action}高度な設定", "xpack.securitySolution.endpoint.policy.artifacts.empty.unassigned.backButtonLabel": "{policyName}ポリシーに戻る", "xpack.securitySolution.endpoint.policy.artifacts.empty.unassigned.content": "現在、{policyName}に割り当てられたアーティファクトがありません。今すぐアーティファクトを割り当てるか、アーティファクトページでアーティファクトを追加および管理してください。", "xpack.securitySolution.endpoint.policy.artifacts.empty.unassigned.noPrivileges.content": "現在、{policyName}に割り当てられたアーティファクトがありません。", @@ -31575,7 +31574,6 @@ "xpack.securitySolution.endpoint.policy.blocklist.list.search.placeholder": "次のフィールドで検索:名前、説明、値", "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.explanation": "オンにすると、ElasticをWindows OSのオフィシャルウイルス対策ソリューションとして登録します。これで Windows Defender も無効になります。", "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.osRestriction": "制限事項", - "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.toggle": "ウイルス対策として登録", "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.type": "ウイルス対策として登録", "xpack.securitySolution.endpoint.policy.details.attack_surface_reduction": "攻撃面削減", "xpack.securitySolution.endpoint.policy.details.attackSurfaceReduction.type": "攻撃面削減", @@ -31585,7 +31583,6 @@ "xpack.securitySolution.endpoint.policy.details.behavior_protection": "悪意のある動作", "xpack.securitySolution.endpoint.policy.details.cancel": "キャンセル", "xpack.securitySolution.endpoint.policy.details.cloudDeploymentLInk": "クラウド展開", - "xpack.securitySolution.endpoint.policy.details.credentialHardening.toggle": "資格情報強化", "xpack.securitySolution.endpoint.policy.details.detect": "検知", "xpack.securitySolution.endpoint.policy.details.detectionRulesLink": "関連する検出ルール", "xpack.securitySolution.endpoint.policy.details.eventCollection": "イベント収集", @@ -31653,7 +31650,6 @@ "xpack.securitySolution.endpoint.policy.multiStepOnboarding.learnMore": "詳細", "xpack.securitySolution.endpoint.policy.multiStepOnboarding.title": "推奨のデフォルト値で統合が保存されます。", "xpack.securitySolution.endpoint.policy.protections.behavior": "悪意ある動作に対する保護", - "xpack.securitySolution.endpoint.policy.protections.blocklist": "ブロックリストが有効にされました", "xpack.securitySolution.endpoint.policy.protections.malware": "マルウェア保護", "xpack.securitySolution.endpoint.policy.protections.memory": "メモリ脅威に対する保護", "xpack.securitySolution.endpoint.policy.protections.ransomware": "ランサムウェア保護", @@ -31686,7 +31682,6 @@ "xpack.securitySolution.endpoint.policyDetails.agentsSummary.onlineTitle": "正常", "xpack.securitySolution.endpoint.policyDetails.agentsSummary.totalTitle": "合計エージェント数", "xpack.securitySolution.endpoint.policyDetails.artifacts.title": "アーチファクト", - "xpack.securitySolution.endpoint.policyDetails.loadError": "エンドポイントポリシー設定を読み込めませんでした", "xpack.securitySolution.endpoint.policyDetails.settings.title": "ポリシー設定", "xpack.securitySolution.endpoint.policyDetails.userNotification.placeholder": "カスタム通知メッセージを入力", "xpack.securitySolution.endpoint.policyDetailsConfig.blocklistTooltip": "このポリシーに関連付けられたブロックリストを有効または無効にします。このブロックリストは、コレクションハッシュ、パス、または署名者です。これはエンドポイントによって悪意があると見なされるプロセスのリストを拡張します。エントリ詳細については、ブロックリストタブを参照してください。", @@ -31695,10 +31690,8 @@ "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.file": "ファイル", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.network": "ネットワーク", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.process": "プロセス", - "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data": "セッションデータを収集", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data.description": "オンにすると、セッションビューに必要な拡張プロセスデータを取り込みます。セッションビューでは、セッションおよびプロセス実行データが視覚的に表示されます。セッションビューデータは、Linuxプロセスモデルに従って整理して表示され、Linuxインフラストラクチャーのプロセス、ユーザー、サービスアクティビティを調査できます。", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data.title": "セッションデータ", - "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.tty_io": "ターミナル出力を取り込む", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.tty_io.tooltip": "オンにすると、ターミナル(tty)出力を収集します。ターミナル出力はセッションビューに表示されます。ターミナルがエコーモードの場合は、実行されたコマンド、入力方法を個別に表示して確認できます。ebpfをサポートするホストでのみ動作します。", "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.file": "ファイル", "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.network": "ネットワーク", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index f8262933b3a83..30c37966d9de6 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -28936,7 +28936,6 @@ "xpack.securitySolution.endpoint.list.totalCount": "正在显示 {totalItemCount, plural, other {# 个终端}}", "xpack.securitySolution.endpoint.list.totalCount.limited": "正在显示 {limit} 个,共 {totalItemCount, plural, other {# 个终端}} 个", "xpack.securitySolution.endpoint.list.transformFailed.message": "所需的转换 {transformId} 当前失败。多数时候,这可以通过 {transformsPage} 解决。要获取更多帮助,请访问{docsPage}", - "xpack.securitySolution.endpoint.policy.advanced.show": "{action} 高级设置", "xpack.securitySolution.endpoint.policy.artifacts.empty.unassigned.backButtonLabel": "返回到 {policyName} 策略", "xpack.securitySolution.endpoint.policy.artifacts.empty.unassigned.content": "当前没有项目已分配给 {policyName}。立即分配项目,或在项目页面上添加和管理项目。", "xpack.securitySolution.endpoint.policy.artifacts.empty.unassigned.noPrivileges.content": "当前没有项目已分配给 {policyName}。", @@ -31571,7 +31570,6 @@ "xpack.securitySolution.endpoint.policy.blocklist.list.search.placeholder": "搜索下面的字段:name、description、value", "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.explanation": "打开可将 Elastic 注册为 Windows 操作系统的正式防病毒解决方案。这也将禁用 Windows Defender。", "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.osRestriction": "限制", - "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.toggle": "注册为防病毒解决方案", "xpack.securitySolution.endpoint.policy.details.antivirusRegistration.type": "注册为防病毒解决方案", "xpack.securitySolution.endpoint.policy.details.attack_surface_reduction": "攻击面减少", "xpack.securitySolution.endpoint.policy.details.attackSurfaceReduction.type": "攻击面减少", @@ -31581,7 +31579,6 @@ "xpack.securitySolution.endpoint.policy.details.behavior_protection": "恶意行为", "xpack.securitySolution.endpoint.policy.details.cancel": "取消", "xpack.securitySolution.endpoint.policy.details.cloudDeploymentLInk": "云部署", - "xpack.securitySolution.endpoint.policy.details.credentialHardening.toggle": "凭据强化", "xpack.securitySolution.endpoint.policy.details.detect": "检测", "xpack.securitySolution.endpoint.policy.details.detectionRulesLink": "相关检测规则", "xpack.securitySolution.endpoint.policy.details.eventCollection": "事件收集", @@ -31649,7 +31646,6 @@ "xpack.securitySolution.endpoint.policy.multiStepOnboarding.learnMore": "了解详情", "xpack.securitySolution.endpoint.policy.multiStepOnboarding.title": "我们将使用建议的默认值保存您的集成。", "xpack.securitySolution.endpoint.policy.protections.behavior": "恶意行为防护", - "xpack.securitySolution.endpoint.policy.protections.blocklist": "阻止列表已启用", "xpack.securitySolution.endpoint.policy.protections.malware": "恶意软件防护", "xpack.securitySolution.endpoint.policy.protections.memory": "内存威胁防护", "xpack.securitySolution.endpoint.policy.protections.ransomware": "勒索软件防护", @@ -31682,7 +31678,6 @@ "xpack.securitySolution.endpoint.policyDetails.agentsSummary.onlineTitle": "运行正常", "xpack.securitySolution.endpoint.policyDetails.agentsSummary.totalTitle": "代理总数", "xpack.securitySolution.endpoint.policyDetails.artifacts.title": "项目", - "xpack.securitySolution.endpoint.policyDetails.loadError": "无法加载终端策略设置", "xpack.securitySolution.endpoint.policyDetails.settings.title": "策略设置", "xpack.securitySolution.endpoint.policyDetails.userNotification.placeholder": "输入您的定制通知消息", "xpack.securitySolution.endpoint.policyDetailsConfig.blocklistTooltip": "启用或禁用与此策略关联的阻止列表。阻止列表是哈希、路径或签名者的集合,它扩充了终端视为恶意的进程列表。查看阻止列表选项卡了解条目详情。", @@ -31691,10 +31686,8 @@ "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.file": "文件", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.network": "网络", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.process": "进程", - "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data": "收集会话数据", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data.description": "打开此项可捕获会话视图所需的扩展进程数据。会话视图为您提供了会话和进程执行数据的视觉表示形式。会话视图数据将根据 Linux 进程模型进行组织,以帮助您调查 Linux 基础架构上的进程、用户和服务活动。", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.session_data.title": "会话数据", - "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.tty_io": "捕获终端输出", "xpack.securitySolution.endpoint.policyDetailsConfig.linux.events.tty_io.tooltip": "打开此项可收集终端 (tty) 输出。终端输出在会话视图中显示,只要终端处于回显模式,您就可以单独查看该输出来了解执行了哪些命令、如何键入这些命令。仅在支持 ebpf 的主机上运行。", "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.file": "文件", "xpack.securitySolution.endpoint.policyDetailsConfig.mac.events.network": "网络", diff --git a/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts b/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts index e167315e0a126..0093119a21e18 100644 --- a/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts +++ b/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts @@ -7,7 +7,8 @@ import expect from '@kbn/expect'; import { IndexedHostsAndAlertsResponse } from '@kbn/security-solution-plugin/common/endpoint/index_data'; -import { popupVersionsMap } from '@kbn/security-solution-plugin/public/management/pages/policy/view/policy_forms/protections/popup_options_to_versions'; +import { PROTECTION_NOTICE_SUPPORTED_ENDPOINT_VERSION } from '@kbn/security-solution-plugin/public/management/pages/policy/view/policy_settings_form/protection_notice_supported_endpoint_version'; +import { getPolicySettingsFormTestSubjects } from '@kbn/security-solution-plugin/public/management/pages/policy/view/policy_settings_form/mocks'; import { FtrProviderContext } from '../../ftr_provider_context'; import { PolicyTestResourceInfo } from '../../services/endpoint_policy'; @@ -28,6 +29,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { describe('When on the Endpoint Policy Details Page', function () { let indexedData: IndexedHostsAndAlertsResponse; + const formTestSubjects = getPolicySettingsFormTestSubjects(); before(async () => { indexedData = await endpointTestResources.loadEndpointData(); @@ -80,91 +82,94 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.policy.navigateToPolicyDetails(policyInfo.packagePolicy.id); }); - it('and the show advanced settings button is clicked', async () => { - await testSubjects.missingOrFail('advancedPolicyPanel'); + it('Should show/hide advanced section when button is clicked', async () => { + await testSubjects.missingOrFail(formTestSubjects.advancedSection.settingsContainer); // Expand await pageObjects.policy.showAdvancedSettingsSection(); - await testSubjects.existOrFail('advancedPolicyPanel'); + await testSubjects.existOrFail(formTestSubjects.advancedSection.settingsContainer); // Collapse await pageObjects.policy.hideAdvancedSettingsSection(); - await testSubjects.missingOrFail('advancedPolicyPanel'); + await testSubjects.missingOrFail(formTestSubjects.advancedSection.settingsContainer); }); }); ['malware', 'ransomware'].forEach((protection) => { - describe(`on the ${protection} protections section`, () => { + describe(`on the ${protection} protections card`, () => { let policyInfo: PolicyTestResourceInfo; + const cardTestSubj: + | typeof formTestSubjects['ransomware'] + | typeof formTestSubjects['malware'] = + formTestSubjects[ + protection as keyof Pick + ]; beforeEach(async () => { policyInfo = await policyTestResources.createPolicy(); await pageObjects.policy.navigateToPolicyDetails(policyInfo.packagePolicy.id); - await testSubjects.existOrFail(`${protection}ProtectionsForm`); }); afterEach(async () => { if (policyInfo) { await policyInfo.cleanup(); + + // @ts-expect-error forcing to undefined + policyInfo = undefined; } }); - it('should show the supported Endpoint version', async () => { - const supportedVersionElement = await testSubjects.findDescendant( - 'policySupportedVersions', - await testSubjects.find(`${protection}ProtectionsForm`) - ); - - expect(await supportedVersionElement.getVisibleText()).to.equal( - 'Agent version ' + popupVersionsMap.get(protection) + it('should show the supported Endpoint version for user notification', async () => { + expect(await testSubjects.getVisibleText(cardTestSubj.notifySupportedVersion)).to.equal( + 'Agent version ' + + PROTECTION_NOTICE_SUPPORTED_ENDPOINT_VERSION[ + protection as keyof typeof PROTECTION_NOTICE_SUPPORTED_ENDPOINT_VERSION + ] ); }); it('should show the custom message text area when the Notify User checkbox is checked', async () => { - expect(await testSubjects.isChecked(`${protection}UserNotificationCheckbox`)).to.be(true); - await testSubjects.existOrFail(`${protection}UserNotificationCustomMessage`); + expect(await testSubjects.isChecked(cardTestSubj.notifyUserCheckbox)).to.be(true); + await testSubjects.existOrFail(cardTestSubj.notifyCustomMessage); }); it('should not show the custom message text area when the Notify User checkbox is unchecked', async () => { - await pageObjects.endpointPageUtils.clickOnEuiCheckbox( - `${protection}UserNotificationCheckbox` - ); - expect(await testSubjects.isChecked(`${protection}UserNotificationCheckbox`)).to.be( - false - ); - await testSubjects.missingOrFail(`${protection}UserNotificationCustomMessage`); + await pageObjects.endpointPageUtils.clickOnEuiCheckbox(cardTestSubj.notifyUserCheckbox); + expect(await testSubjects.isChecked(cardTestSubj.notifyUserCheckbox)).to.be(false); + await testSubjects.missingOrFail(cardTestSubj.notifyCustomMessage); }); it('should show a sample custom message', async () => { - const customMessageBox = await testSubjects.find( - `${protection}UserNotificationCustomMessage` - ); - expect(await customMessageBox.getVisibleText()).equal( + expect(await testSubjects.getVisibleText(cardTestSubj.notifyCustomMessage)).equal( 'Elastic Security {action} {filename}' ); }); - it('should show a tooltip ', async () => { - const malwareTooltipIcon = await testSubjects.find(`${protection}TooltipIcon`); - await malwareTooltipIcon.moveMouseTo(); + it('should show a tooltip on hover', async () => { + await testSubjects.moveMouseTo(cardTestSubj.notifyCustomMessageTooltipIcon); - const malwareTooltip = await testSubjects.find(`${protection}Tooltip`); - expect(await malwareTooltip.getVisibleText()).equal( + expect( + await testSubjects.getVisibleText(cardTestSubj.notifyCustomMessageTooltipInfo) + ).equal( `Selecting the user notification option will display a notification to the host user when ${protection} is prevented or detected.\nThe user notification can be customized in the text box below. Bracketed tags can be used to dynamically populate the applicable action (such as prevented or detected) and the filename.` ); }); it('should preserve a custom notification message upon saving', async () => { - const customMessageBox = await testSubjects.find( - `${protection}UserNotificationCustomMessage` + await testSubjects.setValue(cardTestSubj.notifyCustomMessage, '', { + clearWithKeyboard: true, + }); + await testSubjects.setValue( + cardTestSubj.notifyCustomMessage, + 'a custom notification message @$% 123', + { typeCharByChar: true } ); - await customMessageBox.clearValue(); - await customMessageBox.type('a custom notification message @$% 123'); + await pageObjects.policy.confirmAndSave(); await testSubjects.existOrFail('policyDetailsSuccessMessage'); - expect( - await testSubjects.getVisibleText(`${protection}UserNotificationCustomMessage`) - ).to.equal('a custom notification message @$% 123'); + expect(await testSubjects.getVisibleText(cardTestSubj.notifyCustomMessage)).to.equal( + 'a custom notification message @$% 123' + ); }); }); }); @@ -180,21 +185,28 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { afterEach(async () => { if (policyInfo) { await policyInfo.cleanup(); + + // @ts-expect-error forcing to undefined + policyInfo = undefined; } }); it('should display success toast on successful save', async () => { - await pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_dns'); + await pageObjects.endpointPageUtils.clickOnEuiCheckbox( + formTestSubjects.windowsEvents.dnsCheckbox + ); await pageObjects.policy.confirmAndSave(); await testSubjects.existOrFail('policyDetailsSuccessMessage'); expect(await testSubjects.getVisibleText('policyDetailsSuccessMessage')).to.equal( - `Integration ${policyInfo.packagePolicy.name} has been updated.` + `Success!\nIntegration ${policyInfo.packagePolicy.name} has been updated.` ); }); it('should persist update on the screen', async () => { - await pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_process'); + await pageObjects.endpointPageUtils.clickOnEuiCheckbox( + formTestSubjects.windowsEvents.processCheckbox + ); await pageObjects.policy.confirmAndSave(); await testSubjects.existOrFail('policyDetailsSuccessMessage'); @@ -202,9 +214,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.endpoint.navigateToEndpointList(); await pageObjects.policy.navigateToPolicyDetails(policyInfo.packagePolicy.id); - expect(await (await testSubjects.find('policyWindowsEvent_process')).isSelected()).to.equal( - false - ); + expect( + await ( + await testSubjects.find(formTestSubjects.windowsEvents.processCheckbox) + ).isSelected() + ).to.equal(false); }); it('should have updated policy data in overall Agent Policy', async () => { @@ -212,9 +226,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { // to the generated Agent Policy that is dispatch down to the Elastic Agent. await Promise.all([ - pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_file'), - pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyLinuxEvent_file'), - pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyMacEvent_file'), + pageObjects.endpointPageUtils.clickOnEuiCheckbox( + formTestSubjects.windowsEvents.fileCheckbox + ), + pageObjects.endpointPageUtils.clickOnEuiCheckbox( + formTestSubjects.linuxEvents.fileCheckbox + ), + pageObjects.endpointPageUtils.clickOnEuiCheckbox(formTestSubjects.macEvents.fileCheckbox), ]); await pageObjects.policy.showAdvancedSettingsSection(); @@ -290,7 +308,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { policyInfo.agentPolicy.id, policyInfo.packagePolicy.id ); - await testSubjects.existOrFail('endpointIntegrationPolicyForm'); }); afterEach(async () => { @@ -300,27 +317,41 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); it('should show the endpoint policy form', async () => { - await testSubjects.existOrFail('endpointIntegrationPolicyForm'); + await testSubjects.existOrFail(formTestSubjects.form); }); it('should allow updates to policy items', async () => { - const winDnsEventingCheckbox = await testSubjects.find('policyWindowsEvent_dns'); + const winDnsEventingCheckbox = await testSubjects.find( + formTestSubjects.windowsEvents.dnsCheckbox + ); await pageObjects.ingestManagerCreatePackagePolicy.scrollToCenterOfWindow( winDnsEventingCheckbox ); expect(await winDnsEventingCheckbox.isSelected()).to.be(true); - await pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_dns'); - await pageObjects.policy.waitForCheckboxSelectionChange('policyWindowsEvent_dns', false); + await pageObjects.endpointPageUtils.clickOnEuiCheckbox( + formTestSubjects.windowsEvents.dnsCheckbox + ); + await pageObjects.policy.waitForCheckboxSelectionChange( + formTestSubjects.windowsEvents.dnsCheckbox, + false + ); }); it('should include updated endpoint data when saved', async () => { await pageObjects.ingestManagerCreatePackagePolicy.scrollToCenterOfWindow( - await testSubjects.find('policyWindowsEvent_dns') + await testSubjects.find(formTestSubjects.windowsEvents.dnsCheckbox) + ); + await pageObjects.endpointPageUtils.clickOnEuiCheckbox( + formTestSubjects.windowsEvents.dnsCheckbox + ); + const updatedCheckboxValue = await testSubjects.isSelected( + formTestSubjects.windowsEvents.dnsCheckbox ); - await pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_dns'); - const updatedCheckboxValue = await testSubjects.isSelected('policyWindowsEvent_dns'); - await pageObjects.policy.waitForCheckboxSelectionChange('policyWindowsEvent_dns', false); + await pageObjects.policy.waitForCheckboxSelectionChange( + formTestSubjects.windowsEvents.dnsCheckbox, + false + ); await (await pageObjects.ingestManagerCreatePackagePolicy.findSaveButton(true)).click(); await pageObjects.ingestManagerCreatePackagePolicy.waitForSaveSuccessNotification(true); @@ -331,7 +362,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { ); await pageObjects.policy.waitForCheckboxSelectionChange( - 'policyWindowsEvent_dns', + formTestSubjects.windowsEvents.dnsCheckbox, updatedCheckboxValue ); }); diff --git a/x-pack/test/security_solution_endpoint/page_objects/policy_page.ts b/x-pack/test/security_solution_endpoint/page_objects/policy_page.ts index da4fb936d6655..f2b6452245135 100644 --- a/x-pack/test/security_solution_endpoint/page_objects/policy_page.ts +++ b/x-pack/test/security_solution_endpoint/page_objects/policy_page.ts @@ -6,12 +6,14 @@ */ import expect from '@kbn/expect'; +import { getPolicySettingsFormTestSubjects } from '@kbn/security-solution-plugin/public/management/pages/policy/view/policy_settings_form/mocks'; import { FtrProviderContext } from '../ftr_provider_context'; export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrProviderContext) { const pageObjects = getPageObjects(['common', 'header']); const testSubjects = getService('testSubjects'); const retryService = getService('retry'); + const formTestSubj = getPolicySettingsFormTestSubjects(); return { /** @@ -59,16 +61,8 @@ export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrPr return await testSubjects.find('policyDetailsCancelButton'); }, - /** - * Finds and returns the Advanced Policy Show/Hide Button - */ - async findAdvancedPolicyButton() { - await this.ensureIsOnDetailsPage(); - return await testSubjects.find('advancedPolicyButton'); - }, - async isAdvancedSettingsExpanded() { - return await testSubjects.exists('advancedPolicyPanel'); + return await testSubjects.exists(formTestSubj.advancedSection.settingsContainer); }, /** @@ -76,12 +70,9 @@ export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrPr */ async showAdvancedSettingsSection() { if (!(await this.isAdvancedSettingsExpanded())) { - const expandButton = await this.findAdvancedPolicyButton(); - await expandButton.click(); + await testSubjects.click(formTestSubj.advancedSection.showHideButton); } - - await testSubjects.existOrFail('advancedPolicyPanel'); - await testSubjects.scrollIntoView('advancedPolicyPanel'); + await testSubjects.scrollIntoView(formTestSubj.advancedSection.settingsContainer); }, /** @@ -89,10 +80,9 @@ export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrPr */ async hideAdvancedSettingsSection() { if (await this.isAdvancedSettingsExpanded()) { - const expandButton = await this.findAdvancedPolicyButton(); - await expandButton.click(); + await testSubjects.click(formTestSubj.advancedSection.showHideButton); } - await testSubjects.missingOrFail('advancedPolicyPanel'); + await testSubjects.missingOrFail(formTestSubj.advancedSection.settingsContainer); }, /** @@ -104,7 +94,7 @@ export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrPr }, /** - * ensures that the Details Page is the currently display view + * ensures that the Details Page is currently displayed */ async ensureIsOnDetailsPage() { await testSubjects.existOrFail('policyDetailsPage'); @@ -116,8 +106,6 @@ export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrPr async confirmAndSave() { await this.ensureIsOnDetailsPage(); - const saveButton = await this.findSaveButton(); - // Sometimes, data retrieval errors may have been encountered by other security solution processes // (ex. index fields search here: `x-pack/plugins/security_solution/public/common/containers/source/index.tsx:181`) // which are displayed using one or more Toast messages. This in turn prevents the user from @@ -125,31 +113,11 @@ export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrPr // we'll first check that all toasts are cleared await pageObjects.common.clearAllToasts(); - await saveButton.click(); + await testSubjects.click('policyDetailsSaveButton'); await testSubjects.existOrFail('policyDetailsConfirmModal'); await pageObjects.common.clickConfirmOnModal(); }, - /** - * Finds and returns the Create New policy Policy button displayed on the List page - */ - async findHeaderCreateNewButton() { - // The Create button is initially disabled because we need to first make a call to Ingest - // to retrieve the package version, so that the redirect works as expected. So, we wait - // for that to occur here a well. - await testSubjects.waitForEnabled('headerCreateNewPolicyButton'); - return await testSubjects.find('headerCreateNewPolicyButton'); - }, - - /** - * Used when looking a the Ingest create/edit package policy pages. Finds the endpoint - * custom configuration component - * @param onEditPage - */ - async findPackagePolicyEndpointCustomConfiguration(onEditPage: boolean = false) { - return await testSubjects.find(`endpointPackagePolicy_${onEditPage ? 'edit' : 'create'}`); - }, - /** * Waits for a Checkbox/Radiobutton to have its `isSelected()` value match the provided expected value * @param selector From 0cd98f1dfbeee6cb53832778df94058112fefbb4 Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Wed, 12 Jul 2023 14:31:33 -0500 Subject: [PATCH 84/97] [data discovery] Remove deprecated saved object type references (#161683) ## Summary Cleanup after removing saved object browser client usage. Removing usage of deprecated types, mostly replacing with non-deprecated versions. Closes https://github.com/elastic/kibana/issues/157073 --------- Co-authored-by: Jean-Louis Leysens --- .../search_source/extract_references.ts | 2 +- .../search_source/inject_references.test.ts | 2 +- .../search/search_source/inject_references.ts | 2 +- .../search/session/sessions_mgmt/lib/api.ts | 15 ++++++----- .../search_session_migration.test.ts | 2 +- .../data_views/persistable_state.test.ts | 2 +- .../common/expressions/load_index_pattern.ts | 2 +- .../data_views/common/lib/get_title.ts | 27 ------------------- src/plugins/data_views/common/lib/index.ts | 1 - 9 files changed, 14 insertions(+), 41 deletions(-) delete mode 100644 src/plugins/data_views/common/lib/get_title.ts diff --git a/src/plugins/data/common/search/search_source/extract_references.ts b/src/plugins/data/common/search/search_source/extract_references.ts index 5848cfb232e52..d77d90e3c2845 100644 --- a/src/plugins/data/common/search/search_source/extract_references.ts +++ b/src/plugins/data/common/search/search_source/extract_references.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SavedObjectReference } from '@kbn/core/types'; +import type { SavedObjectReference } from '@kbn/core/server'; import { Filter } from '@kbn/es-query'; import { DataViewPersistableStateService } from '@kbn/data-views-plugin/common'; import { SerializedSearchSourceFields } from './types'; diff --git a/src/plugins/data/common/search/search_source/inject_references.test.ts b/src/plugins/data/common/search/search_source/inject_references.test.ts index 11d098533f449..cce3a2bf6a196 100644 --- a/src/plugins/data/common/search/search_source/inject_references.test.ts +++ b/src/plugins/data/common/search/search_source/inject_references.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SavedObjectReference } from '@kbn/core/types'; +import type { SavedObjectReference } from '@kbn/core/server'; import { SerializedSearchSourceFields } from './types'; import { injectReferences } from './inject_references'; diff --git a/src/plugins/data/common/search/search_source/inject_references.ts b/src/plugins/data/common/search/search_source/inject_references.ts index 09b1be840b5e4..e6fb9160b08be 100644 --- a/src/plugins/data/common/search/search_source/inject_references.ts +++ b/src/plugins/data/common/search/search_source/inject_references.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { SavedObjectReference } from '@kbn/core/types'; +import type { SavedObjectReference } from '@kbn/core/server'; import { DataViewPersistableStateService } from '@kbn/data-views-plugin/common'; import { SerializedSearchSourceFields } from './types'; diff --git a/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts b/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts index ee5b4d504e294..753f43dcbb648 100644 --- a/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts +++ b/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts @@ -7,7 +7,7 @@ */ import { i18n } from '@kbn/i18n'; -import type { ApplicationStart, NotificationsStart, SavedObject } from '@kbn/core/public'; +import type { ApplicationStart, NotificationsStart } from '@kbn/core/public'; import moment from 'moment'; import { from, race, timer } from 'rxjs'; import { mapTo, tap } from 'rxjs/operators'; @@ -26,6 +26,11 @@ import { SearchSessionsConfigSchema } from '../../../../../config'; type LocatorsStart = SharePluginStart['url']['locators']; +interface SearchSessionSavedObject { + id: string; + attributes: PersistedSearchSessionSavedObjectAttributes; +} + function getActions(status: UISearchSessionState) { const actions: ACTION[] = []; actions.push(ACTION.INSPECT); @@ -65,9 +70,7 @@ const mapToUISession = config: SearchSessionsConfigSchema, sessionStatuses: SearchSessionsFindResponse['statuses'] ) => - async ( - savedObject: SavedObject - ): Promise => { + async (savedObject: SearchSessionSavedObject): Promise => { const { name, appId, @@ -152,9 +155,7 @@ export class SearchSessionsMgmtAPI { try { const result = await race(fetch$, timeout$).toPromise(); if (result && result.saved_objects) { - const savedObjects = result.saved_objects as Array< - SavedObject - >; + const savedObjects = result.saved_objects as SearchSessionSavedObject[]; return await Promise.all( savedObjects.map(mapToUISession(this.deps.locators, this.config, result.statuses)) ); diff --git a/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts b/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts index d1c9ef15d4197..4e858089bc656 100644 --- a/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts +++ b/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts @@ -13,7 +13,7 @@ import { SearchSessionSavedObjectAttributesPre$8$0$0, SearchSessionSavedObjectAttributesPre$8$6$0, } from './search_session_migration'; -import { SavedObject } from '@kbn/core/types'; +import type { SavedObject } from '@kbn/core/server'; import { SEARCH_SESSION_TYPE, SearchSessionStatus, SearchStatus } from '../../../common'; import { SavedObjectMigrationContext } from '@kbn/core/server'; import { SavedObjectsUtils } from '@kbn/core-saved-objects-utils-server'; diff --git a/src/plugins/data_views/common/data_views/persistable_state.test.ts b/src/plugins/data_views/common/data_views/persistable_state.test.ts index 473b9ea02bd47..a375e47df88da 100644 --- a/src/plugins/data_views/common/data_views/persistable_state.test.ts +++ b/src/plugins/data_views/common/data_views/persistable_state.test.ts @@ -7,7 +7,7 @@ */ import { DataViewPersistableStateService } from './persistable_state'; -import { SavedObjectReference } from '@kbn/core/types'; +import type { SavedObjectReference } from '@kbn/core/server'; import { DataViewSpec } from '../types'; const { inject, extract } = DataViewPersistableStateService; diff --git a/src/plugins/data_views/common/expressions/load_index_pattern.ts b/src/plugins/data_views/common/expressions/load_index_pattern.ts index 58510bf3a70f9..fcfdf16865ee7 100644 --- a/src/plugins/data_views/common/expressions/load_index_pattern.ts +++ b/src/plugins/data_views/common/expressions/load_index_pattern.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import { ExpressionFunctionDefinition } from '@kbn/expressions-plugin/common'; -import { SavedObjectReference } from '@kbn/core/types'; +import type { SavedObjectReference } from '@kbn/core/server'; import { DataViewsContract } from '../data_views'; import { DataViewSpec } from '..'; diff --git a/src/plugins/data_views/common/lib/get_title.ts b/src/plugins/data_views/common/lib/get_title.ts deleted file mode 100644 index 0dfb274ef240f..0000000000000 --- a/src/plugins/data_views/common/lib/get_title.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { SavedObjectsClientContract } from '@kbn/core/public'; -import { DATA_VIEW_SAVED_OBJECT_TYPE } from '../constants'; -import { DataViewAttributes } from '../types'; - -export async function getTitle( - client: SavedObjectsClientContract, - indexPatternId: string -): Promise { - const savedObject = await client.get( - DATA_VIEW_SAVED_OBJECT_TYPE, - indexPatternId - ); - - if (savedObject.error) { - throw new Error(`Unable to get index-pattern title: ${savedObject.error.message}`); - } - - return savedObject.attributes.title; -} diff --git a/src/plugins/data_views/common/lib/index.ts b/src/plugins/data_views/common/lib/index.ts index 0554232e64cae..e27370682c3cf 100644 --- a/src/plugins/data_views/common/lib/index.ts +++ b/src/plugins/data_views/common/lib/index.ts @@ -7,7 +7,6 @@ */ export { DataViewMissingIndices } from './errors'; -export { getTitle } from './get_title'; export * from './types'; export { validateDataView } from './validate_data_view'; From 4ae94c35024f2037ee02502037b873d93256d200 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Wed, 12 Jul 2023 21:58:13 +0200 Subject: [PATCH 85/97] [Observability] Add feedback buttons for prompts (#160351) Co-authored-by: Sean Heelan --- .../test_suites/core_plugins/rendering.ts | 1 + .../error_sample_co_pilot_prompt.tsx | 1 + x-pack/plugins/apm/server/feature.ts | 4 +- .../components/explain_log_rate_spike.tsx | 1 + .../tabs/processes/process_row.tsx | 1 + x-pack/plugins/infra/server/features.ts | 8 +- .../log_entry_flyout/log_entry_flyout.tsx | 2 + .../observability/common/co_pilot/index.ts | 28 +++ .../{co_pilot.ts => co_pilot/prompts.ts} | 125 +++++------ x-pack/plugins/observability/common/index.ts | 2 +- .../co_pilot_prompt/co_pilot_prompt.tsx | 102 ++++++--- .../co_pilot_prompt_feedback.tsx | 131 +++++++++++ .../create_co_pilot_service.ts | 212 +++++++++++------- .../pages/overview/overview.stories.tsx | 3 + .../public/pages/rules/rules.test.tsx | 5 +- x-pack/plugins/observability/public/plugin.ts | 6 +- .../observability/public/typings/co_pilot.ts | 17 +- .../kibana_react.storybook_decorator.tsx | 3 + .../public/utils/test_helper.tsx | 3 + x-pack/plugins/observability/server/index.ts | 3 + x-pack/plugins/observability/server/plugin.ts | 7 + .../server/routes/copilot/route.ts | 77 ++++++- .../server/routes/register_routes.ts | 12 +- .../observability/server/routes/types.ts | 2 + .../server/services/openai/config.ts | 6 + .../technical_preview_badge.tsx | 31 +++ .../observability_shared/public/index.ts | 2 + .../frame_information_window/index.tsx | 11 +- x-pack/plugins/profiling/server/feature.ts | 4 +- 29 files changed, 592 insertions(+), 218 deletions(-) create mode 100644 x-pack/plugins/observability/common/co_pilot/index.ts rename x-pack/plugins/observability/common/{co_pilot.ts => co_pilot/prompts.ts} (75%) create mode 100644 x-pack/plugins/observability/public/components/co_pilot_prompt/co_pilot_prompt_feedback.tsx create mode 100644 x-pack/plugins/observability_shared/public/components/technical_preview_badge/technical_preview_badge.tsx diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index e711aba9b82a1..7a3b22d62712c 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -273,6 +273,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.upgrade_assistant.featureSet.reindexCorrectiveActions (boolean)', 'xpack.upgrade_assistant.ui.enabled (boolean)', 'xpack.observability.aiAssistant.enabled (boolean)', + 'xpack.observability.aiAssistant.feedback.enabled (boolean)', 'xpack.observability.unsafe.alertDetails.metrics.enabled (boolean)', 'xpack.observability.unsafe.alertDetails.logs.enabled (boolean)', 'xpack.observability.unsafe.alertDetails.uptime.enabled (boolean)', diff --git a/x-pack/plugins/apm/public/components/app/error_group_details/error_sampler/error_sample_co_pilot_prompt.tsx b/x-pack/plugins/apm/public/components/app/error_group_details/error_sampler/error_sample_co_pilot_prompt.tsx index 78631a9db1cc3..dd78c7f090e98 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_details/error_sampler/error_sample_co_pilot_prompt.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_details/error_sampler/error_sample_co_pilot_prompt.tsx @@ -49,6 +49,7 @@ export function ErrorSampleCoPilotPrompt({ )} promptId={CoPilotPromptId.ApmExplainError} params={promptParams} + feedbackEnabled={false} /> diff --git a/x-pack/plugins/apm/server/feature.ts b/x-pack/plugins/apm/server/feature.ts index 09681f01da2d6..292f48bf18156 100644 --- a/x-pack/plugins/apm/server/feature.ts +++ b/x-pack/plugins/apm/server/feature.ts @@ -35,7 +35,7 @@ export const APM_FEATURE = { privileges: { all: { app: [APM_SERVER_FEATURE_ID, 'ux', 'kibana'], - api: [APM_SERVER_FEATURE_ID, 'apm_write', 'rac'], + api: [APM_SERVER_FEATURE_ID, 'apm_write', 'rac', 'ai_assistant'], catalogue: [APM_SERVER_FEATURE_ID], savedObject: { all: [], @@ -56,7 +56,7 @@ export const APM_FEATURE = { }, read: { app: [APM_SERVER_FEATURE_ID, 'ux', 'kibana'], - api: [APM_SERVER_FEATURE_ID, 'rac'], + api: [APM_SERVER_FEATURE_ID, 'rac', 'ai_assistant'], catalogue: [APM_SERVER_FEATURE_ID], savedObject: { all: [], diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx index a8acacd8debd1..c0837f0749b67 100644 --- a/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_details_app_section/components/explain_log_rate_spike.tsx @@ -230,6 +230,7 @@ export const ExplainLogRateSpikes: FC
) : null} diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/processes/process_row.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/processes/process_row.tsx index 646cb82e696bb..c1365364c9ae1 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/processes/process_row.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/processes/process_row.tsx @@ -49,6 +49,7 @@ export const CopilotProcessRow = ({ command }: { command: string }) => { title={explainProcessMessageTitle} params={explainProcessParams} promptId={CoPilotPromptId.InfraExplainProcess} + feedbackEnabled={true} />
diff --git a/x-pack/plugins/infra/server/features.ts b/x-pack/plugins/infra/server/features.ts index e9fec4a5b4f5d..41f60ab5eac9b 100644 --- a/x-pack/plugins/infra/server/features.ts +++ b/x-pack/plugins/infra/server/features.ts @@ -33,7 +33,7 @@ export const METRICS_FEATURE = { all: { app: ['infra', 'metrics', 'kibana'], catalogue: ['infraops', 'metrics'], - api: ['infra', 'rac'], + api: ['infra', 'rac', 'ai_assistant'], savedObject: { all: ['infrastructure-ui-source'], read: ['index-pattern'], @@ -54,7 +54,7 @@ export const METRICS_FEATURE = { read: { app: ['infra', 'metrics', 'kibana'], catalogue: ['infraops', 'metrics'], - api: ['infra', 'rac'], + api: ['infra', 'rac', 'ai_assistant'], savedObject: { all: [], read: ['infrastructure-ui-source', 'index-pattern'], @@ -92,7 +92,7 @@ export const LOGS_FEATURE = { all: { app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging', 'logs'], - api: ['infra', 'rac'], + api: ['infra', 'rac', 'ai_assistant'], savedObject: { all: [infraSourceConfigurationSavedObjectName, logViewSavedObjectName], read: [], @@ -113,7 +113,7 @@ export const LOGS_FEATURE = { read: { app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging', 'logs'], - api: ['infra', 'rac'], + api: ['infra', 'rac', 'ai_assistant'], alerting: { rule: { read: [LOG_DOCUMENT_COUNT_RULE_TYPE_ID], diff --git a/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx index e06064c676a63..70185794f380f 100644 --- a/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx +++ b/x-pack/plugins/logs_shared/public/components/logging/log_entry_flyout/log_entry_flyout.tsx @@ -204,6 +204,7 @@ export const LogEntryFlyout = ({ title={explainLogMessageTitle} params={explainLogMessageParams} promptId={CoPilotPromptId.LogsExplainMessage} + feedbackEnabled={false} /> ) : null} @@ -214,6 +215,7 @@ export const LogEntryFlyout = ({ title={similarLogMessagesTitle} params={similarLogMessageParams} promptId={CoPilotPromptId.LogsFindSimilar} + feedbackEnabled={false} /> ) : null} diff --git a/x-pack/plugins/observability/common/co_pilot/index.ts b/x-pack/plugins/observability/common/co_pilot/index.ts new file mode 100644 index 0000000000000..0d1765402a53e --- /dev/null +++ b/x-pack/plugins/observability/common/co_pilot/index.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export enum OpenAIProvider { + OpenAI = 'openAI', + AzureOpenAI = 'azureOpenAI', +} + +export enum CoPilotPromptId { + ProfilingOptimizeFunction = 'profilingOptimizeFunction', + ApmExplainError = 'apmExplainError', + LogsExplainMessage = 'logsExplainMessage', + LogsFindSimilar = 'logsFindSimilar', + InfraExplainProcess = 'infraExplainProcess', + ExplainLogSpike = 'explainLogSpike', +} + +export type { + CoPilotPromptMap, + CreateChatCompletionResponseChunk, + PromptParamsOf, +} from './prompts'; + +export const loadCoPilotPrompts = () => import('./prompts').then((m) => m.coPilotPrompts); diff --git a/x-pack/plugins/observability/common/co_pilot.ts b/x-pack/plugins/observability/common/co_pilot/prompts.ts similarity index 75% rename from x-pack/plugins/observability/common/co_pilot.ts rename to x-pack/plugins/observability/common/co_pilot/prompts.ts index 9ec88ee24648a..0093232d0c8e7 100644 --- a/x-pack/plugins/observability/common/co_pilot.ts +++ b/x-pack/plugins/observability/common/co_pilot/prompts.ts @@ -5,26 +5,12 @@ * 2.0. */ import * as t from 'io-ts'; -import { - type ChatCompletionRequestMessage, - type CreateChatCompletionResponse, - type CreateChatCompletionResponseChoicesInner, +import type { + ChatCompletionRequestMessage, + CreateChatCompletionResponse, + CreateChatCompletionResponseChoicesInner, } from 'openai'; - -export enum OpenAIProvider { - OpenAI = 'openAI', - AzureOpenAI = 'azureOpenAI', -} - -export enum CoPilotPromptId { - ProfilingExplainFunction = 'profilingExplainFunction', - ProfilingOptimizeFunction = 'profilingOptimizeFunction', - ApmExplainError = 'apmExplainError', - LogsExplainMessage = 'logsExplainMessage', - LogsFindSimilar = 'logsFindSimilar', - InfraExplainProcess = 'infraExplainProcess', - ExplainLogSpike = 'explainLogSpike', -} +import { CoPilotPromptId } from '.'; const PERF_GPT_SYSTEM_MESSAGE = { content: `You are perf-gpt, a helpful assistant for performance analysis and optimisation @@ -83,49 +69,6 @@ const significantFieldValuesRt = t.array( export const coPilotPrompts = { [CoPilotPromptId.ProfilingOptimizeFunction]: prompt({ - params: t.type({ - library: t.string, - functionName: t.string, - }), - messages: ({ library, functionName }) => { - return [ - PERF_GPT_SYSTEM_MESSAGE, - { - content: `Assuming the function ${functionName} from the library ${library} is consuming significant CPU resources. - Suggest ways to optimize or improve the system that involve the ${functionName} function from the - ${library} library. Types of improvements that would be useful to me are improvements that result in: - - - Higher performance so that the system runs faster or uses less CPU - - Better memory efficient so that the system uses less RAM - - Better storage efficient so that the system stores less data on disk. - - Better network I/O efficiency so that less data is sent over the network - - Better disk I/O efficiency so that less data is read and written from disk - - Make up to five suggestions. Your suggestions must meet all of the following criteria: - 1. Your suggestions should be detailed, technical and include concrete examples. - 2. Your suggestions should be specific to improving performance of a system in which the ${functionName} function from - the ${library} library is consuming significant CPU. - 2. If you suggest replacing the function or library with a more efficient replacement you must suggest at least - one concrete replacement. - - If you know of fewer than five ways to improve the performance of a system in which the ${functionName} function from the - ${library} library is consuming significant CPU, then provide fewer than five suggestions. If you do not know of any - way in which to improve the performance then say "I do not know how to improve the performance of systems where - this function is consuming a significant amount of CPU". - - If you have suggestions, the output format should look as follows: - - Here are some suggestions as to how you might optimize your system if ${functionName} in ${library} is consuming - significant CPU resources: - 1. Insert first suggestion - 2. Insert second suggestion - etc.`, - role: 'user', - }, - ]; - }, - }), - [CoPilotPromptId.ProfilingExplainFunction]: prompt({ params: t.type({ library: t.string, functionName: t.string, @@ -135,18 +78,52 @@ export const coPilotPrompts = { PERF_GPT_SYSTEM_MESSAGE, { content: `I am a software engineer. I am trying to understand what a function in a particular - software library does. - - The library is: ${library} - The function is: ${functionName} - - Your task is to describe what the library is and what its use cases are, and to describe what the function - does. The output format should look as follows: - - Library description: Provide a concise description of the library - Library use-cases: Provide a concise description of what the library is typically used for. - Function description: Provide a concise, technical, description of what the function does. - `, + software library does. + + The library is: ${library} + The function is: ${functionName} + + Your have two tasks. Your first task is to desribe what the library is and what its use cases are, and to + describe what the function does. The output format should look as follows: + + Library description: Provide a concise description of the library + Library use-cases: Provide a concise description of what the library is typically used for. + Function description: Provide a concise, technical, description of what the function does. + + Assume the function ${functionName} from the library ${library} is consuming significant CPU resources. + Your second task is to suggest ways to optimize or improve the system that involve the ${functionName} function from the + ${library} library. Types of improvements that would be useful to me are improvements that result in: + + - Higher performance so that the system runs faster or uses less CPU + - Better memory efficient so that the system uses less RAM + - Better storage efficient so that the system stores less data on disk. + - Better network I/O efficiency so that less data is sent over the network + - Better disk I/O efficiency so that less data is read and written from disk + + Make up to five suggestions. Your suggestions must meet all of the following criteria: + 1. Your suggestions should detailed, technical and include concrete examples. + 2. Your suggestions should be specific to improving performance of a system in which the ${functionName} function from + the ${library} library is consuming significant CPU. + 3. If you suggest replacing the function or library with a more efficient replacement you must suggest at least + one concrete replacement. + + If you know of fewer than five ways to improve the performance of a system in which the ${functionName} function from the + ${library} library is consuming significant CPU, then provide fewer than five suggestions. If you do not know of any + way in which to improve the performance then say "I do not know how to improve the performance of systems where + this function is consuming a significant amount of CPU". + + Do not suggest using a CPU profiler. I have already profiled my code. The profiler I used is Elastic Universal Profiler. + If there is specific information I should look for in the profiler output then tell me what information to look for + in the output of Elastic Universal Profiler. + + You must not include URLs, web addresses or websites of any kind in your output. + + If you have suggestions, the output format should look as follows: + + Here are some suggestions as to how you might optimize your system if ${functionName} in ${library} is consuming + significant CPU resources: + 1. Insert first suggestion + 2. Insert second suggestion`, role: 'user', }, ]; diff --git a/x-pack/plugins/observability/common/index.ts b/x-pack/plugins/observability/common/index.ts index 1d4bf57abf285..ab921a8c0c544 100644 --- a/x-pack/plugins/observability/common/index.ts +++ b/x-pack/plugins/observability/common/index.ts @@ -82,4 +82,4 @@ export { SYNTHETICS_WAIT_TIMINGS, } from './field_names/synthetics'; -export { CoPilotPromptId, coPilotPrompts } from './co_pilot'; +export { CoPilotPromptId, loadCoPilotPrompts } from './co_pilot'; diff --git a/x-pack/plugins/observability/public/components/co_pilot_prompt/co_pilot_prompt.tsx b/x-pack/plugins/observability/public/components/co_pilot_prompt/co_pilot_prompt.tsx index 9f762b20e9146..c1241ca62d93b 100644 --- a/x-pack/plugins/observability/public/components/co_pilot_prompt/co_pilot_prompt.tsx +++ b/x-pack/plugins/observability/public/components/co_pilot_prompt/co_pilot_prompt.tsx @@ -8,22 +8,25 @@ import { EuiAccordion, EuiFlexGroup, EuiFlexItem, + EuiHorizontalRule, EuiIcon, EuiLoadingSpinner, EuiPanel, EuiSpacer, EuiText, - EuiToolTip, useEuiTheme, } from '@elastic/eui'; import { css } from '@emotion/css'; import { i18n } from '@kbn/i18n'; -import React, { useEffect, useMemo, useState } from 'react'; +import { TechnicalPreviewBadge } from '@kbn/observability-shared-plugin/public'; +import type { ChatCompletionRequestMessage } from 'openai'; +import React, { useMemo, useState } from 'react'; import useObservable from 'react-use/lib/useObservable'; import { catchError, Observable, of } from 'rxjs'; import { CoPilotPromptId } from '../../../common'; import type { PromptParamsOf } from '../../../common/co_pilot'; import type { CoPilotService, PromptObservableState } from '../../typings/co_pilot'; +import { CoPilotPromptFeedback } from './co_pilot_prompt_feedback'; const cursorCss = css` @keyframes blink { @@ -51,6 +54,7 @@ export interface CoPilotPromptProps { promptId: TPromptId; coPilot: CoPilotService; params: PromptParamsOf; + feedbackEnabled: boolean; } // eslint-disable-next-line import/no-default-export @@ -59,26 +63,47 @@ export default function CoPilotPrompt({ coPilot, promptId, params, + feedbackEnabled, }: CoPilotPromptProps) { const [hasOpened, setHasOpened] = useState(false); const theme = useEuiTheme(); + const [responseTime, setResponseTime] = useState(undefined); + const conversation$ = useMemo(() => { - return hasOpened - ? coPilot - .prompt(promptId, params) - .pipe( - catchError((err) => of({ loading: false, error: err, message: String(err.message) })) - ) - : new Observable(() => {}); - }, [params, promptId, coPilot, hasOpened]); + if (hasOpened) { + setResponseTime(undefined); - const conversation = useObservable(conversation$); + const now = Date.now(); + + const observable = coPilot.prompt(promptId, params).pipe( + catchError((err) => + of({ + messages: [] as ChatCompletionRequestMessage[], + loading: false, + error: err, + message: String(err.message), + }) + ) + ); - useEffect(() => {}, [conversation$]); + observable.subscribe({ + complete: () => { + setResponseTime(Date.now() - now); + }, + }); + + return observable; + } + + return new Observable(() => {}); + }, [params, promptId, coPilot, hasOpened, setResponseTime]); + + const conversation = useObservable(conversation$); const content = conversation?.message ?? ''; + const messages = conversation?.messages; let state: 'init' | 'loading' | 'streaming' | 'error' | 'complete' = 'init'; @@ -94,10 +119,26 @@ export default function CoPilotPrompt({ if (state === 'complete' || state === 'streaming') { inner = ( -

- {content} - {state === 'streaming' ? : <>} -

+ <> +

+ {content} + {state === 'streaming' ? : undefined} +

+ {state === 'complete' ? ( + <> + + {coPilot.isTrackingEnabled() && feedbackEnabled ? ( + + ) : undefined} + + ) : undefined} + ); } else if (state === 'init' || state === 'loading') { inner = ( @@ -128,10 +169,6 @@ export default function CoPilotPrompt({ ); } - const tooltipContent = i18n.translate('xpack.observability.coPilotPrompt.askCoPilot', { - defaultMessage: 'Ask Observability AI Assistent for help', - }); - return ( ({ buttonContent={ - - {title} - + + + + {title} + + + + + {i18n.translate('xpack.observability.coPilotChatPrompt.subtitle', { + defaultMessage: 'Get helpful insights from our Elastic AI Assistant', + })} + + + - - - + } @@ -164,7 +210,9 @@ export default function CoPilotPrompt({ setHasOpened(true); }} > - + + + {inner} diff --git a/x-pack/plugins/observability/public/components/co_pilot_prompt/co_pilot_prompt_feedback.tsx b/x-pack/plugins/observability/public/components/co_pilot_prompt/co_pilot_prompt_feedback.tsx new file mode 100644 index 0000000000000..f51d8061ce491 --- /dev/null +++ b/x-pack/plugins/observability/public/components/co_pilot_prompt/co_pilot_prompt_feedback.tsx @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiText, + useEuiTheme, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import type { ChatCompletionRequestMessage } from 'openai'; +import React, { useCallback, useEffect, useState } from 'react'; +import { CoPilotPromptId } from '../../../common'; +import type { CoPilotService } from '../../typings/co_pilot'; + +interface Props { + coPilot: CoPilotService; + promptId: CoPilotPromptId; + messages?: ChatCompletionRequestMessage[]; + response: string; + responseTime: number; +} + +export function CoPilotPromptFeedback({ + coPilot, + promptId, + messages, + response, + responseTime, +}: Props) { + const theme = useEuiTheme(); + + const [hasSubmittedFeedback, setHasSubmittedFeedback] = useState(false); + + const submitFeedback = useCallback( + (positive: boolean) => { + setHasSubmittedFeedback(true); + if (messages) { + coPilot + .track({ + messages, + response, + responseTime, + promptId, + feedbackAction: positive ? 'thumbsup' : 'thumbsdown', + }) + .catch((err) => {}); + } + }, + [coPilot, promptId, messages, response, responseTime] + ); + + const [hasSubmittedTelemetry, setHasSubmittedTelemetry] = useState(false); + + useEffect(() => { + if (!hasSubmittedTelemetry && messages) { + setHasSubmittedTelemetry(true); + coPilot + .track({ + messages, + response, + responseTime, + promptId, + }) + .catch((err) => {}); + } + }, [coPilot, promptId, messages, response, responseTime, hasSubmittedTelemetry]); + + if (hasSubmittedFeedback) { + return ( + + + + + + + {i18n.translate('xpack.observability.coPilotPrompt.feedbackSubmittedText', { + defaultMessage: + "Thank you for submitting your feedback! We'll use this to improve responses.", + })} + + + + ); + } + + return ( + + + + {i18n.translate('xpack.observability.coPilotPrompt.feedbackActionTitle', { + defaultMessage: 'Did you find this response helpful?', + })} + + + + { + submitFeedback(true); + }} + > + {i18n.translate('xpack.observability.coPilotPrompt.likedFeedbackButtonTitle', { + defaultMessage: 'Yes', + })} + + + + { + submitFeedback(false); + }} + > + {i18n.translate('xpack.observability.coPilotPrompt.dislikedFeedbackButtonTitle', { + defaultMessage: 'No', + })} + + + + ); +} diff --git a/x-pack/plugins/observability/public/context/co_pilot_context/create_co_pilot_service.ts b/x-pack/plugins/observability/public/context/co_pilot_context/create_co_pilot_service.ts index c493bff4e1df8..9f2bdddfe412e 100644 --- a/x-pack/plugins/observability/public/context/co_pilot_context/create_co_pilot_service.ts +++ b/x-pack/plugins/observability/public/context/co_pilot_context/create_co_pilot_service.ts @@ -6,9 +6,13 @@ */ import { type HttpSetup } from '@kbn/core/public'; -import { concatMap, delay, Observable, of } from 'rxjs'; -import { type CreateChatCompletionResponseChunk } from '../../../common/co_pilot'; -import { type CoPilotService, type PromptObservableState } from '../../typings/co_pilot'; +import { ChatCompletionRequestMessage } from 'openai'; +import { BehaviorSubject, concatMap, delay, of } from 'rxjs'; +import { + type CreateChatCompletionResponseChunk, + loadCoPilotPrompts, +} from '../../../common/co_pilot'; +import type { CoPilotService } from '../../typings/co_pilot'; function getMessageFromChunks(chunks: CreateChatCompletionResponseChunk[]) { let message = ''; @@ -18,94 +22,136 @@ function getMessageFromChunks(chunks: CreateChatCompletionResponseChunk[]) { return message; } -export function createCoPilotService({ enabled, http }: { enabled: boolean; http: HttpSetup }) { +export function createCoPilotService({ + enabled, + trackingEnabled, + http, +}: { + enabled: boolean; + trackingEnabled: boolean; + http: HttpSetup; +}) { const service: CoPilotService = { isEnabled: () => enabled, + isTrackingEnabled: () => trackingEnabled, prompt: (promptId, params) => { - return new Observable((observer) => { - observer.next({ chunks: [], loading: true }); - - http - .post(`/internal/observability/copilot/prompts/${promptId}`, { - body: JSON.stringify(params), - asResponse: true, - rawResponse: true, - }) - .then((response) => { - const status = response.response?.status; - - if (!status || status >= 400) { - throw new Error(response.response?.statusText || 'Unexpected error'); - } - - const reader = response.response.body?.getReader(); - - if (!reader) { - throw new Error('Could not get reader from response'); - } - - const decoder = new TextDecoder(); - - const chunks: CreateChatCompletionResponseChunk[] = []; - - let prev: string = ''; + const subject = new BehaviorSubject({ + messages: [] as ChatCompletionRequestMessage[], + loading: true, + message: '', + }); + + loadCoPilotPrompts() + .then((coPilotPrompts) => { + const messages = coPilotPrompts[promptId].messages(params as any); + subject.next({ + messages, + loading: true, + message: '', + }); - function read() { - reader!.read().then(({ done, value }) => { - try { - if (done) { - observer.next({ - chunks, - message: getMessageFromChunks(chunks), - loading: false, + http + .post(`/internal/observability/copilot/prompts/${promptId}`, { + body: JSON.stringify(params), + asResponse: true, + rawResponse: true, + }) + .then((response) => { + const status = response.response?.status; + + if (!status || status >= 400) { + throw new Error(response.response?.statusText || 'Unexpected error'); + } + + const reader = response.response.body?.getReader(); + + if (!reader) { + throw new Error('Could not get reader from response'); + } + + const decoder = new TextDecoder(); + + const chunks: CreateChatCompletionResponseChunk[] = []; + + let prev: string = ''; + + function read() { + reader!.read().then(({ done, value }) => { + try { + if (done) { + subject.next({ + messages, + message: getMessageFromChunks(chunks), + loading: false, + }); + subject.complete(); + return; + } + + let lines = (prev + decoder.decode(value)).split('\n'); + + const lastLine = lines[lines.length - 1]; + + const isPartialChunk = !!lastLine && lastLine !== 'data: [DONE]'; + + if (isPartialChunk) { + prev = lastLine; + lines.pop(); + } else { + prev = ''; + } + + lines = lines + .map((str) => str.substr(6)) + .filter((str) => !!str && str !== '[DONE]'); + + const nextChunks: CreateChatCompletionResponseChunk[] = lines.map((line) => + JSON.parse(line) + ); + + nextChunks.forEach((chunk) => { + chunks.push(chunk); + subject.next({ + messages, + message: getMessageFromChunks(chunks), + loading: true, + }); }); - observer.complete(); + } catch (err) { + subject.error(err); return; } - - let lines = (prev + decoder.decode(value)).split('\n'); - - const lastLine = lines[lines.length - 1]; - - const isPartialChunk = !!lastLine && lastLine !== 'data: [DONE]'; - - if (isPartialChunk) { - prev = lastLine; - lines.pop(); - } else { - prev = ''; - } - - lines = lines - .map((str) => str.substr(6)) - .filter((str) => !!str && str !== '[DONE]'); - - const nextChunks: CreateChatCompletionResponseChunk[] = lines.map((line) => - JSON.parse(line) - ); - - nextChunks.forEach((chunk) => { - chunks.push(chunk); - observer.next({ chunks, message: getMessageFromChunks(chunks), loading: true }); - }); - } catch (err) { - observer.error(err); - return; + read(); + }); + } + + read(); + }) + .catch(async (err) => { + if ('response' in err) { + try { + const responseBody = await err.response.json(); + err.message = responseBody.message; + } catch { + // leave message as-is } - read(); - }); - } - - read(); - - return () => { - reader.cancel(); - }; - }) - .catch((err) => { - observer.error(err); - }); - }).pipe(concatMap((value) => of(value).pipe(delay(50)))); + } + subject.error(err); + }); + }) + .catch((err) => {}); + + return subject.pipe(concatMap((value) => of(value).pipe(delay(25)))); + }, + track: async ({ messages, response, responseTime, feedbackAction, promptId }) => { + await http.post(`/internal/observability/copilot/prompts/${promptId}/track`, { + body: JSON.stringify({ + response, + feedbackAction, + messages, + responseTime, + }), + }); }, }; diff --git a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx index 64d640ef93475..4fd78735bdb68 100644 --- a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx +++ b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx @@ -90,6 +90,9 @@ const withCore = makeDecorator({ compositeSlo: { enabled: false }, aiAssistant: { enabled: false, + feedback: { + enabled: false, + }, }, }; diff --git a/x-pack/plugins/observability/public/pages/rules/rules.test.tsx b/x-pack/plugins/observability/public/pages/rules/rules.test.tsx index db273b2cd018e..0c5a18c5ac9c7 100644 --- a/x-pack/plugins/observability/public/pages/rules/rules.test.tsx +++ b/x-pack/plugins/observability/public/pages/rules/rules.test.tsx @@ -46,8 +46,11 @@ jest.spyOn(pluginContext, 'usePluginContext').mockImplementation(() => ({ compositeSlo: { enabled: false, }, - coPilot: { + aiAssistant: { enabled: false, + feedback: { + enabled: false, + }, }, }, observabilityRuleTypeRegistry: createObservabilityRuleTypeRegistryMock(), diff --git a/x-pack/plugins/observability/public/plugin.ts b/x-pack/plugins/observability/public/plugin.ts index 24c1d2a84ca47..287248538b633 100644 --- a/x-pack/plugins/observability/public/plugin.ts +++ b/x-pack/plugins/observability/public/plugin.ts @@ -93,7 +93,10 @@ export interface ConfigSchema { }; compositeSlo: { enabled: boolean }; aiAssistant?: { - enabled?: boolean; + enabled: boolean; + feedback: { + enabled: boolean; + }; }; } export type ObservabilityPublicSetup = ReturnType; @@ -343,6 +346,7 @@ export class Plugin this.coPilotService = createCoPilotService({ enabled: !!config.aiAssistant?.enabled, http: coreSetup.http, + trackingEnabled: !!config.aiAssistant?.feedback.enabled, }); return { diff --git a/x-pack/plugins/observability/public/typings/co_pilot.ts b/x-pack/plugins/observability/public/typings/co_pilot.ts index b8004f40f8325..3dac1895a8ed3 100644 --- a/x-pack/plugins/observability/public/typings/co_pilot.ts +++ b/x-pack/plugins/observability/public/typings/co_pilot.ts @@ -5,23 +5,28 @@ * 2.0. */ +import type { ChatCompletionRequestMessage } from 'openai'; import type { Observable } from 'rxjs'; -import { - type CoPilotPromptId, - type PromptParamsOf, - type CreateChatCompletionResponseChunk, -} from '../../common/co_pilot'; +import type { CoPilotPromptId, PromptParamsOf } from '../../common/co_pilot'; export interface PromptObservableState { - chunks: CreateChatCompletionResponseChunk[]; message?: string; + messages: ChatCompletionRequestMessage[]; loading: boolean; } export interface CoPilotService { isEnabled: () => boolean; + isTrackingEnabled: () => boolean; prompt( promptId: TPromptId, params: PromptParamsOf ): Observable; + track: (options: { + messages: ChatCompletionRequestMessage[]; + response: string; + promptId: CoPilotPromptId; + feedbackAction?: 'thumbsup' | 'thumbsdown'; + responseTime: number; + }) => Promise; } diff --git a/x-pack/plugins/observability/public/utils/kibana_react.storybook_decorator.tsx b/x-pack/plugins/observability/public/utils/kibana_react.storybook_decorator.tsx index 98b4d32dd7c6c..e56487549a689 100644 --- a/x-pack/plugins/observability/public/utils/kibana_react.storybook_decorator.tsx +++ b/x-pack/plugins/observability/public/utils/kibana_react.storybook_decorator.tsx @@ -37,6 +37,9 @@ export function KibanaReactStorybookDecorator(Story: ComponentType) { compositeSlo: { enabled: false }, aiAssistant: { enabled: false, + feedback: { + enabled: false, + }, }, }; const mockTheme: CoreTheme = { diff --git a/x-pack/plugins/observability/public/utils/test_helper.tsx b/x-pack/plugins/observability/public/utils/test_helper.tsx index ac0a79975af75..c979eaef6b879 100644 --- a/x-pack/plugins/observability/public/utils/test_helper.tsx +++ b/x-pack/plugins/observability/public/utils/test_helper.tsx @@ -41,6 +41,9 @@ const defaultConfig: ConfigSchema = { compositeSlo: { enabled: false }, aiAssistant: { enabled: false, + feedback: { + enabled: false, + }, }, }; diff --git a/x-pack/plugins/observability/server/index.ts b/x-pack/plugins/observability/server/index.ts index 3ea386dbb1d99..1f06f63c5de00 100644 --- a/x-pack/plugins/observability/server/index.ts +++ b/x-pack/plugins/observability/server/index.ts @@ -62,6 +62,9 @@ export const config: PluginConfigDescriptor = { unsafe: true, aiAssistant: { enabled: true, + feedback: { + enabled: true, + }, }, }, schema: configSchema, diff --git a/x-pack/plugins/observability/server/plugin.ts b/x-pack/plugins/observability/server/plugin.ts index ab74a511b265f..ccd437865f47d 100644 --- a/x-pack/plugins/observability/server/plugin.ts +++ b/x-pack/plugins/observability/server/plugin.ts @@ -25,6 +25,7 @@ import { SharePluginSetup } from '@kbn/share-plugin/server'; import { SpacesPluginSetup } from '@kbn/spaces-plugin/server'; import type { GuidedOnboardingPluginSetup } from '@kbn/guided-onboarding-plugin/server'; import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server'; +import { CloudSetup } from '@kbn/cloud-plugin/server'; import { kubernetesGuideId, kubernetesGuideConfig, @@ -57,6 +58,7 @@ interface PluginSetup { share: SharePluginSetup; spaces?: SpacesPluginSetup; usageCollection?: UsageCollectionSetup; + cloud?: CloudSetup; } interface PluginStart { @@ -249,7 +251,12 @@ export class ObservabilityPlugin implements Plugin { core.getStartServices().then(([coreStart, pluginStart]) => { registerRoutes({ core, + config, dependencies: { + pluginsSetup: { + ...plugins, + core, + }, ruleDataService, getRulesClientWithRequest: pluginStart.alerting.getRulesClientWithRequest, getOpenAIClient: () => openAIService?.client, diff --git a/x-pack/plugins/observability/server/routes/copilot/route.ts b/x-pack/plugins/observability/server/routes/copilot/route.ts index f0a6e7bae56b4..13606616bdc96 100644 --- a/x-pack/plugins/observability/server/routes/copilot/route.ts +++ b/x-pack/plugins/observability/server/routes/copilot/route.ts @@ -6,11 +6,13 @@ */ import Boom from '@hapi/boom'; import { ServerRoute } from '@kbn/server-route-repository'; +import axios from 'axios'; import * as t from 'io-ts'; import { map } from 'lodash'; -import { CreateChatCompletionResponse } from 'openai'; +import { ChatCompletionRequestMessageRoleEnum, CreateChatCompletionResponse } from 'openai'; import { Readable } from 'stream'; -import { CoPilotPromptMap, coPilotPrompts } from '../../../common/co_pilot'; +import { CoPilotPromptMap } from '../../../common/co_pilot'; +import { coPilotPrompts } from '../../../common/co_pilot/prompts'; import { createObservabilityServerRoute } from '../create_observability_server_route'; import { ObservabilityRouteCreateOptions, ObservabilityRouteHandlerResources } from '../types'; @@ -31,7 +33,7 @@ const promptRoutes: { body: prompt.params, }), options: { - tags: [], + tags: ['ai_assistant'], }, handler: async (resources): Promise => { const client = resources.dependencies.getOpenAIClient(); @@ -40,12 +42,79 @@ const promptRoutes: { throw Boom.notImplemented(); } - return client.chatCompletion.create(prompt.messages(resources.params.body as any)); + try { + return await client.chatCompletion.create(prompt.messages(resources.params.body as any)); + } catch (error: any) { + if (axios.isAxiosError(error) && error.response?.status === 401) { + throw Boom.forbidden(error.response?.statusText); + } + throw error; + } }, }); }) ); +const trackRoute = createObservabilityServerRoute({ + endpoint: 'POST /internal/observability/copilot/prompts/{promptId}/track', + params: t.type({ + path: t.type({ + promptId: t.string, + }), + body: t.intersection([ + t.type({ + responseTime: t.number, + messages: t.array( + t.intersection([ + t.type({ + role: t.union([ + t.literal(ChatCompletionRequestMessageRoleEnum.System), + t.literal(ChatCompletionRequestMessageRoleEnum.User), + t.literal(ChatCompletionRequestMessageRoleEnum.Assistant), + ]), + content: t.string, + }), + t.partial({ + name: t.string, + }), + ]) + ), + response: t.string, + }), + t.partial({ + feedbackAction: t.union([t.literal('thumbsup'), t.literal('thumbsdown')]), + }), + ]), + }), + options: { + tags: ['ai_assistant'], + }, + handler: async (resources): Promise => { + const { params, config } = resources; + + if (!config.aiAssistant?.enabled) { + throw Boom.notImplemented(); + } + + const feedbackBody = { + prompt_name: params.path.promptId, + feedback_action: params.body.feedbackAction, + model: + 'openAI' in config.aiAssistant.provider + ? config.aiAssistant.provider.openAI.model + : config.aiAssistant.provider.azureOpenAI.resourceName, + response_time: params.body.responseTime, + conversation: [ + ...params.body.messages.map(({ role, content }) => ({ role, content })), + { role: 'system', content: params.body.response }, + ], + }; + + await axios.post(config.aiAssistant.feedback.url, feedbackBody); + }, +}); + export const observabilityCoPilotRouteRepository = { ...promptRoutes, + ...trackRoute, }; diff --git a/x-pack/plugins/observability/server/routes/register_routes.ts b/x-pack/plugins/observability/server/routes/register_routes.ts index a296fe86a7be7..0d982c6bf48ca 100644 --- a/x-pack/plugins/observability/server/routes/register_routes.ts +++ b/x-pack/plugins/observability/server/routes/register_routes.ts @@ -16,12 +16,14 @@ import { } from '@kbn/server-route-repository'; import axios from 'axios'; import * as t from 'io-ts'; +import { ObservabilityConfig } from '..'; import { getHTTPResponseCode, ObservabilityError } from '../errors'; import { IOpenAIClient } from '../services/openai/types'; import { ObservabilityRequestHandlerContext } from '../types'; import { AbstractObservabilityServerRouteRepository } from './types'; interface RegisterRoutes { + config: ObservabilityConfig; core: CoreSetup; repository: AbstractObservabilityServerRouteRepository; logger: Logger; @@ -29,12 +31,15 @@ interface RegisterRoutes { } export interface RegisterRoutesDependencies { + pluginsSetup: { + core: CoreSetup; + }; ruleDataService: RuleDataPluginService; getRulesClientWithRequest: (request: KibanaRequest) => RulesClientApi; getOpenAIClient: () => IOpenAIClient | undefined; } -export function registerRoutes({ repository, core, logger, dependencies }: RegisterRoutes) { +export function registerRoutes({ config, repository, core, logger, dependencies }: RegisterRoutes) { const routes = Object.values(repository); const router = core.http.createRouter(); @@ -60,13 +65,14 @@ export function registerRoutes({ repository, core, logger, dependencies }: Regis params ?? t.strict({}) ); - const data = (await handler({ + const data = await handler({ + config, context, request, logger, params: decodedParams, dependencies, - })) as any; + }); if (data === undefined) { return response.noContent(); diff --git a/x-pack/plugins/observability/server/routes/types.ts b/x-pack/plugins/observability/server/routes/types.ts index e782053e592ae..866bd3c79c1d1 100644 --- a/x-pack/plugins/observability/server/routes/types.ts +++ b/x-pack/plugins/observability/server/routes/types.ts @@ -10,6 +10,7 @@ import { KibanaRequest, Logger } from '@kbn/core/server'; import { ObservabilityServerRouteRepository } from './get_global_observability_server_route_repository'; import { ObservabilityRequestHandlerContext } from '../types'; import { RegisterRoutesDependencies } from './register_routes'; +import { ObservabilityConfig } from '..'; export type { ObservabilityServerRouteRepository }; @@ -18,6 +19,7 @@ export interface ObservabilityRouteHandlerResources { dependencies: RegisterRoutesDependencies; logger: Logger; request: KibanaRequest; + config: ObservabilityConfig; } export interface ObservabilityRouteCreateOptions { diff --git a/x-pack/plugins/observability/server/services/openai/config.ts b/x-pack/plugins/observability/server/services/openai/config.ts index ba6e4f6b2ba08..88a9060b71386 100644 --- a/x-pack/plugins/observability/server/services/openai/config.ts +++ b/x-pack/plugins/observability/server/services/openai/config.ts @@ -24,6 +24,12 @@ export const azureOpenAIConfig = schema.object({ export const observabilityCoPilotConfig = schema.object({ enabled: schema.boolean({ defaultValue: false }), + feedback: schema.object({ + enabled: schema.boolean({ defaultValue: false }), + url: schema.string({ + defaultValue: `https://0d0uj24psl.execute-api.us-east-1.amazonaws.com/gaifeedback`, + }), + }), provider: schema.oneOf([openAIConfig, azureOpenAIConfig]), }); diff --git a/x-pack/plugins/observability_shared/public/components/technical_preview_badge/technical_preview_badge.tsx b/x-pack/plugins/observability_shared/public/components/technical_preview_badge/technical_preview_badge.tsx new file mode 100644 index 0000000000000..4055d5c888b91 --- /dev/null +++ b/x-pack/plugins/observability_shared/public/components/technical_preview_badge/technical_preview_badge.tsx @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiBetaBadge, IconType } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; + +type Props = { + icon?: IconType; +} & Pick, 'size' | 'style'>; + +export function TechnicalPreviewBadge({ icon = 'beaker', size, style }: Props) { + return ( + + ); +} diff --git a/x-pack/plugins/observability_shared/public/index.ts b/x-pack/plugins/observability_shared/public/index.ts index 6bf3b67716a91..7308265827d09 100644 --- a/x-pack/plugins/observability_shared/public/index.ts +++ b/x-pack/plugins/observability_shared/public/index.ts @@ -35,6 +35,8 @@ export { export type { SectionLinkProps } from './components/section/section'; export { LoadWhenInView } from './components/load_when_in_view/get_load_when_in_view_lazy'; +export { TechnicalPreviewBadge } from './components/technical_preview_badge/technical_preview_badge'; + export { InspectorContextProvider } from './contexts/inspector/inspector_context'; export type { AddInspectorRequest } from './contexts/inspector/inspector_context'; export { useInspectorContext } from './contexts/inspector/use_inspector_context'; diff --git a/x-pack/plugins/profiling/public/components/frame_information_window/index.tsx b/x-pack/plugins/profiling/public/components/frame_information_window/index.tsx index db3fc5d10c9dd..bd059f74cbfea 100644 --- a/x-pack/plugins/profiling/public/components/frame_information_window/index.tsx +++ b/x-pack/plugins/profiling/public/components/frame_information_window/index.tsx @@ -105,16 +105,6 @@ export function FrameInformationWindow({ frame, totalSamples, totalSeconds, samp {coPilotService?.isEnabled() && promptParams ? ( <> - - - diff --git a/x-pack/plugins/profiling/server/feature.ts b/x-pack/plugins/profiling/server/feature.ts index 13e064364b7b8..446a436145c77 100644 --- a/x-pack/plugins/profiling/server/feature.ts +++ b/x-pack/plugins/profiling/server/feature.ts @@ -27,7 +27,7 @@ export const PROFILING_FEATURE = { read: [], }, ui: ['show'], - api: [PROFILING_SERVER_FEATURE_ID], + api: [PROFILING_SERVER_FEATURE_ID, 'ai_assistant'], }, read: { app: [PROFILING_SERVER_FEATURE_ID, 'ux', 'kibana'], @@ -36,7 +36,7 @@ export const PROFILING_FEATURE = { read: [], }, ui: ['show'], - api: [PROFILING_SERVER_FEATURE_ID], + api: [PROFILING_SERVER_FEATURE_ID, 'ai_assistant'], }, }, }; From c2559ac655c3b169e35c4d44f636570db56628f4 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Wed, 12 Jul 2023 17:03:22 -0500 Subject: [PATCH 86/97] [Enterprise Search] update error message when search app not found for field caps (#161811) ## Summary Updated "Could not find engine" to "Could not find search application" --- .../plugins/enterprise_search/common/types/error_codes.ts | 2 +- .../routes/enterprise_search/search_applications.test.ts | 4 ++-- .../server/routes/enterprise_search/search_applications.ts | 7 +++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/enterprise_search/common/types/error_codes.ts b/x-pack/plugins/enterprise_search/common/types/error_codes.ts index 6724e35f057b8..db5e5d825128c 100644 --- a/x-pack/plugins/enterprise_search/common/types/error_codes.ts +++ b/x-pack/plugins/enterprise_search/common/types/error_codes.ts @@ -11,7 +11,6 @@ export enum ErrorCode { CONNECTOR_DOCUMENT_ALREADY_EXISTS = 'connector_document_already_exists', CRAWLER_ALREADY_EXISTS = 'crawler_already_exists', DOCUMENT_NOT_FOUND = 'document_not_found', - ENGINE_NOT_FOUND = 'engine_not_found', INDEX_ALREADY_EXISTS = 'index_already_exists', INDEX_NOT_FOUND = 'index_not_found', MAPPING_UPDATE_FAILED = 'mapping_update_failed', @@ -22,6 +21,7 @@ export enum ErrorCode { RESOURCE_NOT_FOUND = 'resource_not_found', SEARCH_APPLICATION_ALREADY_EXISTS = 'search_application_already_exists', SEARCH_APPLICATION_NAME_INVALID = 'search_application_name_invalid', + SEARCH_APPLICATION_NOT_FOUND = 'search_application_not_found', UNAUTHORIZED = 'unauthorized', UNCAUGHT_EXCEPTION = 'uncaught_exception', } diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search_applications.test.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search_applications.test.ts index 20f2709e41647..09273e8c12432 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search_applications.test.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search_applications.test.ts @@ -548,9 +548,9 @@ describe('engines routes', () => { expect(mockRouter.response.customError).toHaveBeenCalledWith({ body: { attributes: { - error_code: 'engine_not_found', + error_code: 'search_application_not_found', }, - message: 'Could not find engine', + message: 'Could not find search application', }, statusCode: 404, }); diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search_applications.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search_applications.ts index 67af98c13dec9..5b58fd1b9b4ec 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search_applications.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search_applications.ts @@ -230,8 +230,11 @@ export function registerSearchApplicationsRoutes({ log, router }: RouteDependenc } catch (e) { if (isNotFoundException(e)) { return createError({ - errorCode: ErrorCode.ENGINE_NOT_FOUND, - message: 'Could not find engine', + errorCode: ErrorCode.SEARCH_APPLICATION_NOT_FOUND, + message: i18n.translate( + 'xpack.enterpriseSearch.server.routes.fetchSearchApplicationFieldCapabilities.error', + { defaultMessage: 'Could not find search application' } + ), response, statusCode: 404, }); From 2caa973c61735002df5b9aaf444f1ca543c279c1 Mon Sep 17 00:00:00 2001 From: Kevin Qualters <56408403+kqualters-elastic@users.noreply.github.com> Date: Wed, 12 Jul 2023 18:09:13 -0400 Subject: [PATCH 87/97] [Security Solution] [Timeline] Add filter.meta.relation to timeline filters saved object mapping (#161722) ## Summary Without this mapping, timelines that try to make use of a top level OR filter from the unified search filter builder cannot be saved, everything works as expected with this change. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../current_mappings.json | 91 ++++++++++--------- .../group2/check_registered_types.test.ts | 2 +- .../saved_object_mappings/timelines.ts | 3 + 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index 689606cd5f19f..cb78e060d6edc 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -616,6 +616,30 @@ } } }, + "tag": { + "properties": { + "name": { + "type": "text" + }, + "description": { + "type": "text" + }, + "color": { + "type": "text" + } + } + }, + "search": { + "dynamic": false, + "properties": { + "title": { + "type": "text" + }, + "description": { + "type": "text" + } + } + }, "alert": { "dynamic": false, "properties": { @@ -874,30 +898,6 @@ } } }, - "tag": { - "properties": { - "name": { - "type": "text" - }, - "description": { - "type": "text" - }, - "color": { - "type": "text" - } - } - }, - "search": { - "dynamic": false, - "properties": { - "title": { - "type": "text" - }, - "description": { - "type": "text" - } - } - }, "graph-workspace": { "properties": { "description": { @@ -2259,6 +2259,14 @@ } } }, + "infrastructure-monitoring-log-view": { + "dynamic": false, + "properties": { + "name": { + "type": "text" + } + } + }, "ml-job": { "properties": { "job_id": { @@ -2796,6 +2804,9 @@ }, "value": { "type": "text" + }, + "relation": { + "type": "keyword" } } }, @@ -2932,14 +2943,6 @@ "dynamic": false, "properties": {} }, - "infrastructure-monitoring-log-view": { - "dynamic": false, - "properties": { - "name": { - "type": "text" - } - } - }, "metrics-explorer-view": { "dynamic": false, "properties": {} @@ -2976,18 +2979,6 @@ } } }, - "enterprise_search_telemetry": { - "dynamic": false, - "properties": {} - }, - "app_search_telemetry": { - "dynamic": false, - "properties": {} - }, - "workplace_search_telemetry": { - "dynamic": false, - "properties": {} - }, "apm-indices": { "dynamic": false, "properties": {} @@ -3019,5 +3010,17 @@ "type": "text" } } + }, + "enterprise_search_telemetry": { + "dynamic": false, + "properties": {} + }, + "app_search_telemetry": { + "dynamic": false, + "properties": {} + }, + "workplace_search_telemetry": { + "dynamic": false, + "properties": {} } } diff --git a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts index f139103b55c54..c1cfca07017bc 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts @@ -134,7 +134,7 @@ describe('checking migration metadata changes on all registered SO types', () => "security-rule": "07abb4d7e707d91675ec0495c73816394c7b521f", "security-solution-signals-migration": "9d99715fe5246f19de2273ba77debd2446c36bb1", "siem-detection-engine-rule-actions": "54f08e23887b20da7c805fab7c60bc67c428aff9", - "siem-ui-timeline": "670a02b3c2a399bca781ff1e4781793b208b471a", + "siem-ui-timeline": "820b5a7c478cd4d5ae9cd92ce0d05ac988fee69c", "siem-ui-timeline-note": "0a32fb776907f596bedca292b8c646496ae9c57b", "siem-ui-timeline-pinned-event": "082daa3ce647b33873f6abccf340bdfa32057c8d", "slo": "2048ab6791df2e1ae0936f29c20765cb8d2fcfaa", diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/timelines.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/timelines.ts index 4f7df977662f4..d133e9b114f8b 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/timelines.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/timelines.ts @@ -213,6 +213,9 @@ export const timelineSavedObjectMappings: SavedObjectsType['mappings'] = { value: { type: 'text', }, + relation: { + type: 'keyword', + }, }, }, exists: { From 2e049ce7f2a8a036c4554458ab30f694c25b8afa Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 13 Jul 2023 00:55:08 -0400 Subject: [PATCH 88/97] [api-docs] 2023-07-13 Daily api_docs build (#161823) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/397 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_chat_provider.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 10 +- api_docs/deprecations_by_plugin.mdx | 8 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.devdocs.json | 15 + api_docs/enterprise_search.mdx | 4 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.devdocs.json | 15 + api_docs/fleet.mdx | 4 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- ...kbn_core_elasticsearch_server.devdocs.json | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.devdocs.json | 12 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- ...ore_saved_objects_api_browser.devdocs.json | 12 - .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- ...kbn_core_saved_objects_common.devdocs.json | 92 --- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_assistant.devdocs.json | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_generate_csv_types.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/logs_shared.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.devdocs.json | 522 ++++++++++-------- api_docs/observability.mdx | 7 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.devdocs.json | 33 ++ api_docs/observability_shared.mdx | 4 +- api_docs/osquery.devdocs.json | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 14 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/reporting_export_types.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.devdocs.json | 110 +++- api_docs/security.mdx | 4 +- api_docs/security_solution.mdx | 2 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualization_ui_components.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 555 files changed, 1009 insertions(+), 935 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 0e0ab4c5351bb..9f12661e7ff19 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index e1d6969e6cb84..f5278b36aef3c 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 5f9b975ef5fc9..15dfa7ff4439d 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 0a5831e816202..ad4805be0cf52 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index eea9228dc13a1..ae8e773311363 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index 187f8cac08c6e..ed8b3e1f1ed8c 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 1657a91e26407..76c5159216a35 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 1a7203b15daf6..8052e456920be 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index 04935e3ace356..a1735de3babc1 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index b478758a50d19..95743d690468f 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 53ed6a8ebd0c5..d03065155b01f 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 56591da514f14..e222daeb0d63b 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index e3cda9d91fcec..d6b8d2cdc8a0e 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index b8aab15383ec9..36de0f67b98e9 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index d68eada8d0f96..e44f3096a919a 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index a1dedd8339ebd..d54ef4ce06e7d 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 5c6eded66b586..116caa6814780 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 224ea106b3a70..0c1b2133ba6d3 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index c735c48198d89..89a40411b80d1 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index 88b58e1006119..067e817d560c8 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index f6243d77450ae..ff947b5a790b0 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 2311c13d9dab5..726fe75c64c81 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 050b47851a7cd..1c446d0c9b28e 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index b4fc147092548..55d48f0ca2f48 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 52eb0626413b2..3cc21f11e7d86 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index db9e19d2ca004..ea37083c9666a 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 7f25bf9e7a12f..1d31279da0b48 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index c1e0159f6932f..593b3d7e16e2b 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index d700893466595..a85ad030751b8 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index af4c7eb88725a..4acf03b61b04d 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index e4fe9a051c9e4..ec8b6df08a684 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index ca4cf96b7503f..217b6c9b73aec 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index f8cf8ffbe522b..469a2054c6296 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -31,7 +31,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | @kbn/core-saved-objects-browser-internal, @kbn/core, savedObjects, embeddable, presentationUtil, visualizations, aiops, ml, dataVisualizer, dashboardEnhanced, graph, uptime, lens, securitySolution, eventAnnotation, @kbn/core-saved-objects-browser-mocks | - | | | @kbn/core, savedObjects, embeddable, visualizations, canvas, graph, ml, @kbn/core-saved-objects-common, @kbn/core-saved-objects-server, actions, alerting, savedSearch, enterpriseSearch, securitySolution, taskManager, @kbn/core-saved-objects-server-internal, @kbn/core-saved-objects-api-server | - | | | observability, @kbn/securitysolution-data-table, securitySolution | - | -| | @kbn/core-saved-objects-api-browser, @kbn/core, savedObjects, savedObjectsManagement, visualizations, savedObjectsTagging, eventAnnotation, lens, graph, dashboard, savedObjectsTaggingOss, kibanaUtils, expressions, dataViews, data, embeddable, controls, uiActionsEnhanced, cases, maps, canvas, dashboardEnhanced, globalSearchProviders, infra | - | +| | @kbn/core-saved-objects-api-browser, @kbn/core, savedObjects, savedObjectsManagement, visualizations, savedObjectsTagging, eventAnnotation, lens, graph, dashboard, savedObjectsTaggingOss, kibanaUtils, expressions, data, embeddable, controls, uiActionsEnhanced, cases, maps, canvas, dashboardEnhanced, globalSearchProviders, infra | - | | | monitoring | - | | | alerting, discover, securitySolution | - | | | @kbn/core-saved-objects-api-browser, @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-api-server-internal, @kbn/core-saved-objects-import-export-server-internal, @kbn/core-saved-objects-server-internal, home, fleet, graph, lists, osquery, securitySolution, alerting | - | @@ -44,7 +44,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | @kbn/securitysolution-data-table, securitySolution | - | | | securitySolution | - | | | securitySolution | - | -| | @kbn/core-saved-objects-api-browser, @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-api-server, @kbn/core, home, data, savedObjectsTagging, canvas, savedObjects, @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-import-export-server-internal, savedObjectsTaggingOss, lists, securitySolution, upgradeAssistant, savedObjectsManagement, synthetics, @kbn/core-ui-settings-server-internal | - | +| | @kbn/core-saved-objects-api-browser, @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-api-server, @kbn/core, home, savedObjectsTagging, canvas, savedObjects, @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-import-export-server-internal, savedObjectsTaggingOss, lists, securitySolution, upgradeAssistant, savedObjectsManagement, synthetics, @kbn/core-ui-settings-server-internal | - | | | @kbn/core-saved-objects-migration-server-internal, actions, dataViews, data, alerting, lens, cases, savedObjectsTagging, visualizations, savedSearch, canvas, graph, lists, maps, securitySolution, dashboard, @kbn/core-test-helpers-so-type-serializer | - | | | lists, securitySolution, @kbn/securitysolution-io-ts-list-types | - | | | lists, securitySolution, @kbn/securitysolution-io-ts-list-types | - | @@ -66,13 +66,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | data, discover, imageEmbeddable, embeddable | - | | | @kbn/core-saved-objects-browser-mocks, discover, @kbn/core-saved-objects-browser-internal | - | | | advancedSettings, discover | - | -| | @kbn/core-saved-objects-browser, @kbn/core-saved-objects-browser-internal, @kbn/core, dataViews, home, savedObjects, visualizations, lens, visTypeTimeseries, @kbn/core-saved-objects-browser-mocks | - | +| | @kbn/core-saved-objects-browser, @kbn/core-saved-objects-browser-internal, @kbn/core, home, savedObjects, visualizations, lens, visTypeTimeseries, @kbn/core-saved-objects-browser-mocks | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, savedObjects, dashboard | - | | | @kbn/core-saved-objects-browser-mocks, home, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, savedObjects, visualizations | - | | | @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-mocks, savedObjects, presentationUtil, dashboard, dashboardEnhanced, @kbn/core-saved-objects-browser-internal | - | -| | @kbn/core-saved-objects-browser-mocks, dataViews, savedObjects, dashboard, dashboardEnhanced, @kbn/core-saved-objects-browser-internal | - | +| | @kbn/core-saved-objects-browser-mocks, savedObjects, dashboard, dashboardEnhanced, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-mocks, savedObjects, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-browser-internal | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, savedObjects | - | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 83536ed983ed0..418fbd650446d 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -520,8 +520,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [get_columns.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [get_columns.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [get_columns.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks) | - | | | [session_service.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/session/session_service.ts#:~:text=authc) | - | | | [data_table.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx#:~:text=executeTriggerActions), [data_table.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx#:~:text=executeTriggerActions) | - | -| | [api.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts#:~:text=SavedObject), [api.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject), [search_session_migration.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/search/saved_objects/search_session_migration.test.ts#:~:text=SavedObject)+ 2 more | - | -| | [extract_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/extract_references.ts#:~:text=SavedObjectReference), [extract_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/extract_references.ts#:~:text=SavedObjectReference), [extract_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/extract_references.ts#:~:text=SavedObjectReference), [inject_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inject_references.ts#:~:text=SavedObjectReference), [inject_references.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/search/search_source/inject_references.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/persistable_state.ts#:~:text=SavedObjectReference)+ 3 more | - | +| | [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/filters/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/persistable_state.ts#:~:text=SavedObjectReference), [persistable_state.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/common/query/persistable_state.ts#:~:text=SavedObjectReference) | - | | | [query.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data/server/saved_objects/query.ts#:~:text=convertToMultiNamespaceTypeVersion) | - | @@ -559,9 +558,6 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=removeScriptedField) | - | | | [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getNonScriptedFields) | - | | | [data_view.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.ts#:~:text=getScriptedFields), [data_view.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.ts#:~:text=getScriptedFields), [data_views.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_views.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields), [data_view.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getScriptedFields) | - | -| | [get_title.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/lib/get_title.ts#:~:text=SavedObjectsClientContract), [get_title.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/lib/get_title.ts#:~:text=SavedObjectsClientContract) | - | -| | [get_title.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/lib/get_title.ts#:~:text=get) | - | -| | [load_index_pattern.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/expressions/load_index_pattern.ts#:~:text=SavedObjectReference), [load_index_pattern.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/expressions/load_index_pattern.ts#:~:text=SavedObjectReference), [persistable_state.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/persistable_state.test.ts#:~:text=SavedObjectReference), [persistable_state.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/common/data_views/persistable_state.test.ts#:~:text=SavedObjectReference) | - | | | [data_views.ts](https://github.com/elastic/kibana/tree/main/src/plugins/data_views/server/saved_objects/data_views.ts#:~:text=convertToMultiNamespaceTypeVersion) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index e096bc42395d4..96988b210d293 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index d0290715c0f57..114ff24510c73 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 4a80c4c6ec659..5b4f2716b00cb 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index bf5d24a0bc322..48dda991d719b 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 828b0e4f1e0d4..22c335a6bdabf 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 1f61f06f10b54..5df5a15d89f59 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 3306b885aba81..5df39f9b59f6b 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index ecf23355c6f43..0bc3b60a9a7cd 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.devdocs.json b/api_docs/enterprise_search.devdocs.json index 17434038d906a..9481ef8ff7ad5 100644 --- a/api_docs/enterprise_search.devdocs.json +++ b/api_docs/enterprise_search.devdocs.json @@ -119,6 +119,21 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false + }, + { + "parentPluginId": "enterpriseSearch", + "id": "def-server.CURRENT_CONNECTORS_JOB_INDEX", + "type": "string", + "tags": [], + "label": "CURRENT_CONNECTORS_JOB_INDEX", + "description": [], + "signature": [ + "\".elastic-connectors-v1\"" + ], + "path": "x-pack/plugins/enterprise_search/server/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false } ], "objects": [ diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 79d6bf3e05471..a40603ac30816 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/te | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 9 | 0 | 9 | 0 | +| 10 | 0 | 10 | 0 | ## Client diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 0b5b81b8a877d..72a974ca15d84 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 9bb15b0f32bfa..5364940099acc 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 13d89a9e5c378..ae328fd1164ba 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index 12961303978f4..2694ba0efd2bf 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index fb0b8ee37a743..e7967eeaca8f3 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index d9c36252d16aa..8373065ef030e 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index f1fb11d646678..6d4eb1c010933 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 00bed41e99c19..19a7dd01ee13e 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 89af764aa6440..44793c00bee3d 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index c75de62e3dbcf..7e4d7ed60343a 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 289424f4e8834..71d6bb1e7adf4 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index cd0da75ef6e8c..c37e371814afc 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 43d6601702c5a..590ef7c4d56fb 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index ccb5a2aedf6b2..ebc9b628e0530 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 87d7897eb200d..d86d0ae3509af 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index 16bccdb267bd2..85f18ea25427c 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 74d25081b5d1d..ee2b844da1d64 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index f3f58b2a27a3e..a58ece1eff7a5 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 41fd3419f5de7..90661245687eb 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index c63612795faac..637d41fac6a29 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 542d4ed08c338..97587fa96493e 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 1ddacd877c509..8e94b08147a8e 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index 954bde0d1ae86..fcecdf57b2296 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index d66beb287620d..a5eb0c5dd285e 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -22615,6 +22615,21 @@ "path": "x-pack/plugins/fleet/common/types/models/epm.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.RegistryDataStream.RegistryDataStreamKeys.routing_rules", + "type": "Array", + "tags": [], + "label": "[RegistryDataStreamKeys.routing_rules]", + "description": [], + "signature": [ + "RegistryDataStreamRoutingRules", + "[] | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/models/epm.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index ee043ce78284d..5533a02e4c496 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1178 | 3 | 1062 | 38 | +| 1179 | 3 | 1063 | 39 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 0e1917e4dfc2e..d2193fc298d04 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index e68c91fe3785f..200ddd283c321 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 00c3488be64b6..dfb874a8fc880 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index 5109497abe2a6..4a484b4aa6d1d 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 5473efb3ca053..8a7a53787ab26 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 47fa332ba3a94..d6f48042ed408 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 9475dc7e3aa86..4e69c773e8a69 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index a329af66d5229..12f05417a90a8 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index c3528e6d07eec..9a54b5f51ee88 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 130d069ce98f9..f9ddf1e99904b 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index f7d908b6ecdc9..0f7b2497feed4 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 2dea9f2aa6f6b..1a2d7e193ff44 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 39705e2c53c6b..1fbb9cecf8b29 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index b2916aac20659..b9b520e36dfb8 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 909956bbee755..694d2f230f177 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 36510a7c30fca..126f0a46f88cb 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 84d0e52258020..74a8353bbed7d 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 00fcd4d59e31c..34d69381a912f 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 8cdfd63966f52..8b4ea10b16aba 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 9ea23175e6de5..23f311d7a545c 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 73baa1123393d..f9f6d8e319a20 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 9978be994a024..3072792c8f147 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index c2fc51e9d93fc..cc63c9a594184 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 0d676f679653d..59119a02ed685 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 37f318fe7ef19..78e0682b0677f 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 6ae83a48eccc5..7621ada3f324d 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index fcb1aac9ea596..9172324ca42bf 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 568f91c78e9ed..ff368b72062dc 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index ba2472670cd1e..d5eb1e50d7a6c 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index 2985544798bfa..a06e63ba0db57 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index e1b6a605379ec..c2b8678b95d5c 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index d98c2ec0ef6ea..dd345f00b4991 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 168bb6090af47..a620ff7fa7f31 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 53d8ef0f3bc6d..5c0d6aebc6bfd 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index fd8f651f682ad..57a4692ea3eb9 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 4b2c661c20cb7..a6f8482805bfa 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index 5331221829399..f504890769f02 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 0eaf6c9da09ec..e76b045c08ae6 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index 56f814d71e837..70ed7fb5db79f 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 0475270a89c9c..232eb1874d230 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 30a71e5a065c2..86ba55286ac5c 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index 362b437d4571f..346f8be9ed795 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index 48d8865d9f46d..cb07834904447 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index 7df7bbf4623f3..c6bdced42d5eb 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index b50777fa84f3f..59bf34fc96f24 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 91f3c5d1783fd..babd8c5419aea 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 6847b4d1aa9c5..d4c0bd5f4855d 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 173935358b865..50250c0c082ac 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 8f30a416545c9..6f87d89ab7d18 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index dcb36cb93ed9a..92336f64a9a8b 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index e43811ca0ad9b..2c847f6fe747f 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index ee34b37d18ebf..cd24830e79c03 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index af1abb215ef59..d02e04fa133c9 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 66115be3595c8..0aaeeda661da6 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 450d8f94b3d4e..20cb5788d863d 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index d771c1444b659..d69dcf27afdb4 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 5639638acd338..75b470d49a335 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index da1a800000ea9..9b7f724e197e7 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index 16014275cde75..4260c6c974c8e 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 3c69264a4447e..07703d075984c 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 803ecd24b551b..f6b533e2eef39 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index 2554c3f481917..f1b64c8e792fc 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 27d5a83e89bd6..11da7cb2dab13 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index bd0ed426dd0c1..74d3338be9d8c 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 8b9db1d51925b..d547d5b2b4096 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index 07fa8f8f4eb62..89cbbf7641566 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 30eb4b6ab447b..816606360771e 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 691eec8bbca0a..6c92c2a164684 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 031bf9c813dae..44779d3375ccc 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index 164655c32e2b6..8cadef61b790d 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index 043b7b8b09f1e..2850149229722 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 976073d213970..aa8fba73ae214 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index 9ce15f163884d..c5e555af955cf 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index f9e3dd0fe8de6..31520988ae26c 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index 94fb1bdf52115..6938d95c58330 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index 9dd0c9346a59c..19f86b54f69b6 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index b39044c98c3a7..29fc1342f239d 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 45c1b0db7bc28..967f1860d3bdd 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index be85be3196dae..2e0e4e0f10f03 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index ec9a3430517d8..78afd614e82fe 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 8fc0b69f4e28e..4cd3e1b19f738 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index 5b075501e2588..209597139058c 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index 36b1e169cfa0f..ff0d8c4a668f2 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 92057cff0d689..aa7d63ff68aa6 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 0f2aa9ddf107c..3b23da0ad24f8 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index b26062d911f90..a01948504beaa 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index d5e16036d1832..25d170c7d20ef 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index c9d9f5a7dc47a..f76a7596fd664 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index ba4012f9e1b5b..c5e360c68faca 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 0120e09dda4ce..1cec70fc49ab5 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.devdocs.json b/api_docs/kbn_core_elasticsearch_server.devdocs.json index 6aeb9884c1073..2a0b684c65c01 100644 --- a/api_docs/kbn_core_elasticsearch_server.devdocs.json +++ b/api_docs/kbn_core_elasticsearch_server.devdocs.json @@ -974,7 +974,7 @@ "Headers used for authentication against Elasticsearch" ], "signature": [ - "{ date?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; from?: string | string[] | undefined; etag?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; range?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ date?: string | string[] | undefined; warning?: string | string[] | undefined; range?: string | string[] | undefined; from?: string | string[] | undefined; location?: string | string[] | undefined; etag?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "packages/core/elasticsearch/core-elasticsearch-server/src/client/scopeable_request.ts", "deprecated": false, diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index 7ebe337c6b8bd..3ac4ccbab444e 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 26bb228e9927d..24ac35dca54af 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index 693476127fbfb..47b92383acd3c 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 27f403baec1f3..b3d29d65cdf9b 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index bac9aa54d4b24..d5d2e0bea2fbb 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index a31537a571fb2..da01635129551 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index ecf2953f4f04d..cbc07a2cee616 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 8ae2f16af5826..76d388fed0e4b 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index d1b80948307e4..c31e8c64cb02a 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 5c0e2fd063232..0adc8ebfe00d5 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 1cb080085fccc..babca9b4374b5 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index d2025835c5831..29532576b39fb 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index b0a7979e93218..c241df41f3e97 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 5da02bdcb2ffc..8c2c1f74b9e9e 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 70844f98340c4..b10b9dc6b10fb 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index c40605c832b27..edf4d89eac14a 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index efdb8900c0efe..a1154770e00e1 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index 1b29d689faab9..6073146d38323 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 5da0c253aba57..2976a7d7e17aa 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index 215d78a294f86..db999bfae8965 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index 2f9a87bc1df4f..f2095d830f97f 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index 648cdd93b856c..94faccd55fa77 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index 431c1c8ebf6d6..6db6f8d25b767 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index 7cbce11e04844..771c814b023d7 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index f9a388d3bed9b..b6ccef6c3723c 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.devdocs.json b/api_docs/kbn_core_http_server.devdocs.json index e2bbe5507cc44..8f3d3158648cb 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -754,7 +754,7 @@ "The headers associated with the request." ], "signature": [ - "{ date?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; from?: string | string[] | undefined; etag?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; range?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ date?: string | string[] | undefined; warning?: string | string[] | undefined; range?: string | string[] | undefined; from?: string | string[] | undefined; location?: string | string[] | undefined; etag?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "packages/core/http/core-http-server/src/router/raw_request.ts", "deprecated": false, @@ -11045,7 +11045,7 @@ "\nReadonly copy of incoming request headers." ], "signature": [ - "{ date?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; from?: string | string[] | undefined; etag?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; range?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ date?: string | string[] | undefined; warning?: string | string[] | undefined; range?: string | string[] | undefined; from?: string | string[] | undefined; location?: string | string[] | undefined; etag?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "packages/core/http/core-http-server/src/router/request.ts", "deprecated": false, @@ -12605,7 +12605,7 @@ "tags": [], "label": "access", "description": [ - "\nDefines intended request origin of the route:\n- public. The route is public, declared stable and intended for external access.\n In the future, may require an incomming request to contain a specified header.\n- internal. The route is internal and intended for internal access only.\n\nIf not declared, infers access from route path:\n- access =`internal` for '/internal' route path prefix\n- access = `public` for everything else" + "\nDefines intended request origin of the route:\n- public. The route is public, declared stable and intended for external access.\n In the future, may require an incomming request to contain a specified header.\n- internal. The route is internal and intended for internal access only.\n\nDefaults to 'internal' If not declared," ], "signature": [ "\"internal\" | \"public\" | undefined" @@ -16047,7 +16047,7 @@ "\nHttp request headers to read." ], "signature": [ - "{ date?: string | string[] | undefined; warning?: string | string[] | undefined; location?: string | string[] | undefined; from?: string | string[] | undefined; etag?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; range?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" + "{ date?: string | string[] | undefined; warning?: string | string[] | undefined; range?: string | string[] | undefined; from?: string | string[] | undefined; location?: string | string[] | undefined; etag?: string | string[] | undefined; accept?: string | string[] | undefined; \"accept-language\"?: string | string[] | undefined; \"accept-patch\"?: string | string[] | undefined; \"accept-ranges\"?: string | string[] | undefined; \"access-control-allow-credentials\"?: string | string[] | undefined; \"access-control-allow-headers\"?: string | string[] | undefined; \"access-control-allow-methods\"?: string | string[] | undefined; \"access-control-allow-origin\"?: string | string[] | undefined; \"access-control-expose-headers\"?: string | string[] | undefined; \"access-control-max-age\"?: string | string[] | undefined; \"access-control-request-headers\"?: string | string[] | undefined; \"access-control-request-method\"?: string | string[] | undefined; age?: string | string[] | undefined; allow?: string | string[] | undefined; \"alt-svc\"?: string | string[] | undefined; authorization?: string | string[] | undefined; \"cache-control\"?: string | string[] | undefined; connection?: string | string[] | undefined; \"content-disposition\"?: string | string[] | undefined; \"content-encoding\"?: string | string[] | undefined; \"content-language\"?: string | string[] | undefined; \"content-length\"?: string | string[] | undefined; \"content-location\"?: string | string[] | undefined; \"content-range\"?: string | string[] | undefined; \"content-type\"?: string | string[] | undefined; cookie?: string | string[] | undefined; expect?: string | string[] | undefined; expires?: string | string[] | undefined; forwarded?: string | string[] | undefined; host?: string | string[] | undefined; \"if-match\"?: string | string[] | undefined; \"if-modified-since\"?: string | string[] | undefined; \"if-none-match\"?: string | string[] | undefined; \"if-unmodified-since\"?: string | string[] | undefined; \"last-modified\"?: string | string[] | undefined; origin?: string | string[] | undefined; pragma?: string | string[] | undefined; \"proxy-authenticate\"?: string | string[] | undefined; \"proxy-authorization\"?: string | string[] | undefined; \"public-key-pins\"?: string | string[] | undefined; referer?: string | string[] | undefined; \"retry-after\"?: string | string[] | undefined; \"sec-websocket-accept\"?: string | string[] | undefined; \"sec-websocket-extensions\"?: string | string[] | undefined; \"sec-websocket-key\"?: string | string[] | undefined; \"sec-websocket-protocol\"?: string | string[] | undefined; \"sec-websocket-version\"?: string | string[] | undefined; \"set-cookie\"?: string | string[] | undefined; \"strict-transport-security\"?: string | string[] | undefined; tk?: string | string[] | undefined; trailer?: string | string[] | undefined; \"transfer-encoding\"?: string | string[] | undefined; upgrade?: string | string[] | undefined; \"user-agent\"?: string | string[] | undefined; vary?: string | string[] | undefined; via?: string | string[] | undefined; \"www-authenticate\"?: string | string[] | undefined; } & { [header: string]: string | string[] | undefined; }" ], "path": "packages/core/http/core-http-server/src/router/headers.ts", "deprecated": false, @@ -16353,7 +16353,7 @@ "\nSet of well-known HTTP headers." ], "signature": [ - "\"date\" | \"warning\" | \"location\" | \"from\" | \"etag\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\"" + "\"date\" | \"warning\" | \"range\" | \"from\" | \"location\" | \"etag\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\"" ], "path": "packages/core/http/core-http-server/src/router/headers.ts", "deprecated": false, @@ -17459,7 +17459,7 @@ "\nHttp response headers to set." ], "signature": [ - "Record | Record<\"date\" | \"warning\" | \"location\" | \"from\" | \"etag\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"range\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]>" + "Record | Record<\"date\" | \"warning\" | \"range\" | \"from\" | \"location\" | \"etag\" | \"accept\" | \"accept-language\" | \"accept-patch\" | \"accept-ranges\" | \"access-control-allow-credentials\" | \"access-control-allow-headers\" | \"access-control-allow-methods\" | \"access-control-allow-origin\" | \"access-control-expose-headers\" | \"access-control-max-age\" | \"access-control-request-headers\" | \"access-control-request-method\" | \"age\" | \"allow\" | \"alt-svc\" | \"authorization\" | \"cache-control\" | \"connection\" | \"content-disposition\" | \"content-encoding\" | \"content-language\" | \"content-length\" | \"content-location\" | \"content-range\" | \"content-type\" | \"cookie\" | \"expect\" | \"expires\" | \"forwarded\" | \"host\" | \"if-match\" | \"if-modified-since\" | \"if-none-match\" | \"if-unmodified-since\" | \"last-modified\" | \"origin\" | \"pragma\" | \"proxy-authenticate\" | \"proxy-authorization\" | \"public-key-pins\" | \"referer\" | \"retry-after\" | \"sec-websocket-accept\" | \"sec-websocket-extensions\" | \"sec-websocket-key\" | \"sec-websocket-protocol\" | \"sec-websocket-version\" | \"set-cookie\" | \"strict-transport-security\" | \"tk\" | \"trailer\" | \"transfer-encoding\" | \"upgrade\" | \"user-agent\" | \"vary\" | \"via\" | \"www-authenticate\", string | string[]>" ], "path": "packages/core/http/core-http-server/src/router/headers.ts", "deprecated": false, diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 24669ef76fef7..96b41a5ef180a 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 23a09858462f5..c53bbf9c0cb05 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 402aa93e9b2c5..5d18120f474da 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index d2f1ffca13139..6709630e1127a 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 5ae37e56f21b7..2876d33b14f3c 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index 17877019697e2..c68d4ebb7b9f6 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index e83cc31b28190..9300dd5403ed2 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index fef7b98ad4ae5..19218eeeb0bc5 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 22a22a33170c8..82c23c51f2cac 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index 5a8e77da56fa5..3e1275ecb779d 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index 1177a824e92ee..8338056c152cc 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index b5702c33ec5cb..7d52748dead01 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index d78ce87a2d630..11de43cdc82ae 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index 96342a2d71aaa..230b0c3e8c2ce 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index 62779de54d792..ab34cc42b940e 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index 9e4d1bca827fd..20bbbb8883518 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index eddf2a13143df..92e7e69c7646b 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 6787935eb8584..c7221624f35ce 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 99be57fa5ae14..06f41a57cb1ff 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index a84adc015efdb..d96d61e84fbe3 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index 969abe2ba843e..d3049399cdcb3 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index 178372659de9f..769c76c04fe3f 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index cd07cbeb503f5..824617b579599 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index cc4417259162a..b5611371ab7d8 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index f56eb8b931c24..3d305788a5077 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index c85ad3d88efa4..74f08a008e206 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index 72d00b36c7605..002138972d995 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index e793f3309ae71..050342c97717e 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 51250a42629cd..cc4236a7a04fa 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index d748e6c111653..5c4ab4074ab5e 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 3e7be9fdac160..4586b1ef3373a 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index fcb2c1ad441fc..fa2a31a6205d0 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index f1ae03938e1e0..66d75ee886ac6 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index cd53753661d92..09e4448c2e956 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index 326bc9b696620..7bbf1ac0d3dec 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index b8992d708726f..66072ad97528c 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 7b2a7418caf84..fa824d883ebe6 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index ff8a92cfc953b..783aa573f84c2 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index 04a54990deb0f..ef61a15e60017 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 224884d3806a0..5ccf7174db502 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 5feae586499d8..1717891a7115c 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index b0a1ae726fd77..9f4008313135c 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index c501425c79f14..3a74cdbb2ad5b 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index d8c19431838f1..ba662708fd64c 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index 2893edfec3f32..c41c5062aa565 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.devdocs.json b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json index 7af458553d3a3..cb7c6b8810907 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_browser.devdocs.json @@ -902,14 +902,6 @@ "plugin": "@kbn/core", "path": "src/core/public/index.ts" }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/lib/get_title.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/lib/get_title.ts" - }, { "plugin": "home", "path": "src/plugins/home/public/application/kibana_services.ts" @@ -1743,10 +1735,6 @@ "plugin": "@kbn/core-saved-objects-browser-mocks", "path": "packages/core/saved-objects/core-saved-objects-browser-mocks/src/saved_objects_service.mock.ts" }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/lib/get_title.ts" - }, { "plugin": "savedObjects", "path": "src/plugins/saved_objects/public/saved_object/helpers/initialize_saved_object.ts" diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index fd9067a8e6158..4da78adc42468 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index e2ca55bc4e9e8..4362de7b6be02 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index 7e57cd32304ed..78532a7032059 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index 926bd86c02dbf..7266a40032075 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 98d0ac6e86376..21e78fe177f1b 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index bab69b2c56342..42d8f8f377b83 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index 7e6742810e67a..cd203fad90fab 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 991f6be78d252..2218de8a2fe22 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.devdocs.json b/api_docs/kbn_core_saved_objects_common.devdocs.json index cd61e4bd76984..8eba223b71c72 100644 --- a/api_docs/kbn_core_saved_objects_common.devdocs.json +++ b/api_docs/kbn_core_saved_objects_common.devdocs.json @@ -1213,18 +1213,6 @@ "plugin": "home", "path": "src/plugins/home/server/services/sample_data/sample_data_registry.ts" }, - { - "plugin": "data", - "path": "src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/public/search/session/sessions_mgmt/lib/api.ts" - }, { "plugin": "savedObjectsTagging", "path": "x-pack/plugins/saved_objects_tagging/public/ui_api/get_table_column_definition.tsx" @@ -1453,42 +1441,6 @@ "plugin": "savedObjectsManagement", "path": "src/plugins/saved_objects_management/server/lib/find_relationships.test.ts" }, - { - "plugin": "data", - "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/server/search/saved_objects/search_session_migration.test.ts" - }, { "plugin": "synthetics", "path": "x-pack/plugins/synthetics/public/apps/synthetics/state/monitor_list/api.ts" @@ -2334,34 +2286,6 @@ "plugin": "expressions", "path": "src/plugins/expressions/common/executor/executor.ts" }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/expressions/load_index_pattern.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/common/search/search_source/extract_references.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/common/search/search_source/extract_references.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/common/search/search_source/extract_references.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/common/search/search_source/inject_references.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/common/search/search_source/inject_references.ts" - }, { "plugin": "data", "path": "src/plugins/data/common/query/filters/persistable_state.ts" @@ -2734,14 +2658,6 @@ "plugin": "globalSearchProviders", "path": "x-pack/plugins/global_search_providers/server/providers/saved_objects/map_object_to_result.test.ts" }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/data_views/persistable_state.test.ts" - }, - { - "plugin": "dataViews", - "path": "src/plugins/data_views/common/data_views/persistable_state.test.ts" - }, { "plugin": "expressions", "path": "src/plugins/expressions/common/executor/executor.test.ts" @@ -2754,14 +2670,6 @@ "plugin": "expressions", "path": "src/plugins/expressions/common/executor/executor.test.ts" }, - { - "plugin": "data", - "path": "src/plugins/data/common/search/search_source/inject_references.test.ts" - }, - { - "plugin": "data", - "path": "src/plugins/data/common/search/search_source/inject_references.test.ts" - }, { "plugin": "lens", "path": "x-pack/plugins/lens/common/locator/locator.ts" diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index f53ae5edb4826..28ffd4be36b30 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 258aa0c529bbb..be802b9444f0e 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index 973ba8d4b52bb..beffba5db75bc 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 6fe2b0f2e8056..7cd8ac84fc940 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index e0f57ed175730..b2553c8b7132d 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index b3690a047be7e..0e4f67e68df09 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 66640e5420539..52d1c333567c3 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index d1822d583e682..2c3c6c3c5b386 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 0e68dc683e23f..b27f0e3aa63ab 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index ef8864b10629e..3b5e4b646b6fc 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index d9f01d08ba38e..f7c73c872fcbb 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index bbb3a83f5c960..9d9a783ed469a 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index d4ee4d97d6369..70a7d567d87d2 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index 25d9f5ad30d6d..6284e192e9745 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index 9227e74ee3c33..dd2e747e69100 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index e35964915ee67..7226da9ff1194 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index 0d42a174b8907..402053b2511c1 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index d861dd91eaa01..f98e734ba0c85 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index 0e7b965fd0cc9..316731894ec08 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index f21c6cf50b3a4..ef96520cd8d06 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 0c99b9a118cc1..d035a28221fba 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 6d248ab515df9..29dbacf9025ca 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 57c64fff3b87a..9958562bd293e 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 071698435008d..1585fc6f5b346 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 8cff18c922317..7c938bf838fff 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index 136900eac8199..cb415dedcf87c 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 168fe47ca307e..3c5b615232c94 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index 578f04c2c5e34..42330a3b90e20 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index c3fdc4fd9dda3..fb6d27268c6c0 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index acffe2a0f19f6..eac2398eadf85 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 58b2c0cc99911..487c8d6b6978a 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index 7ca96d1e141be..4b9acc72dd408 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index 51beded6653cf..ec6c2e36f8287 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index 4beadaf63d268..9afe2e777c398 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 2d1bf314f08b3..9a16b292e90a7 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-mocks'] --- import kbnCoreUserSettingsServerMocksObj from './kbn_core_user_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 8ec181c0de112..34e611ff5a4c8 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 2ce03d0103e57..9a5b0dbb7c957 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 7bc4bd91ba2c5..cc4126bb50c06 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index b5ee9a2e6d5f1..6a25144310430 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index d4f49580e0d1b..73accf99299ce 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_analytics.mdx b/api_docs/kbn_deeplinks_analytics.mdx index cb5a24f2fae69..f2eee176558d2 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-analytics'] --- import kbnDeeplinksAnalyticsObj from './kbn_deeplinks_analytics.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_devtools.mdx b/api_docs/kbn_deeplinks_devtools.mdx index 4a855e2d32a26..bcb83d34a64f9 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 0dde10bf0bfbc..cb5b653560357 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_management.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index 0bf5b3649cef4..67eecc850f3df 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index dad07297d9f48..a1eab7d606d3f 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index cccc0ab00111c..71f3b0309537b 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index 87c65f1115b60..ee131463e91dc 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-analytics'] --- import kbnDefaultNavAnalyticsObj from './kbn_default_nav_analytics.devdocs.json'; diff --git a/api_docs/kbn_default_nav_devtools.mdx b/api_docs/kbn_default_nav_devtools.mdx index c03336b1150ee..62537fe4c1834 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-devtools'] --- import kbnDefaultNavDevtoolsObj from './kbn_default_nav_devtools.devdocs.json'; diff --git a/api_docs/kbn_default_nav_management.mdx b/api_docs/kbn_default_nav_management.mdx index 1d2937812cedb..530013cafb912 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-management'] --- import kbnDefaultNavManagementObj from './kbn_default_nav_management.devdocs.json'; diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index d5b56ac76b984..1395e842f88d8 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-ml'] --- import kbnDefaultNavMlObj from './kbn_default_nav_ml.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 2a712353f6780..859fd3ebb15dd 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 4cfd7903f48fc..bd9cc94a57032 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index d310a7ffc618b..c6a7ae588b82f 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 57e0d6c31600a..ab8a1e337faf9 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index ca03416fafdcc..954dd7d4166cc 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 0366678c15ecb..24771c25a64ea 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_dom_drag_drop.mdx b/api_docs/kbn_dom_drag_drop.mdx index 58928b38b8d0c..0d7703dd0ad8b 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dom-drag-drop'] --- import kbnDomDragDropObj from './kbn_dom_drag_drop.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 39725a714fac7..c6a477dc2e2b4 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index bee49db0feafb..4b6d571c93f75 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 5a7a6a6549157..0105733724ec9 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.devdocs.json b/api_docs/kbn_elastic_assistant.devdocs.json index 393e7ea5d5bda..3685f00b7b9b9 100644 --- a/api_docs/kbn_elastic_assistant.devdocs.json +++ b/api_docs/kbn_elastic_assistant.devdocs.json @@ -460,7 +460,7 @@ "signature": [ "{ connectorId?: string | undefined; defaultSystemPromptId?: string | undefined; provider?: ", "OpenAiProviderType", - " | undefined; }" + " | undefined; model?: string | undefined; }" ], "path": "x-pack/packages/kbn-elastic-assistant/impl/assistant_context/types.tsx", "deprecated": false, diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index fdbc701fd75f8..22de25998b737 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 4583437116ed3..b4728c59e9cb6 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index c192f40b3e6ff..d99444e6d694f 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index 231888b12b04b..3d94e2e2467dd 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index c0fcbe324fdf9..4fdd9d9aa5892 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 17938a13b4862..1801c44f0802a 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 8d7f731a5df0e..c3562691f4b59 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index c0f6860c9f179..c3648fff54cbf 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index e1f856d0ab9f4..49432057fb7cb 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 88d87cac61f0e..46c842e191a78 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 289566868f693..82aef15de730f 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 20fd1cfa45650..0007e6a55495d 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index 8e18ba2d8464e..2dcee172c5978 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index 1985b1736ebcb..98035cabd6a92 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index 9e82ac0fcc836..d480599d61f01 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 70cde35d17f58..8b1a4f6c3dc3b 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 82f91568699a3..9b9abc6e897d8 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index cf0a8393637c8..43d7ce55e4e87 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index 72be599ece123..4f233991d579a 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index ee6ff9632aec1..9ac01d4d88485 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index 2662cf16f57a3..14fed28478710 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index d89316dc9b5c1..9eaade5c41805 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index a1b3bbcf539d8..46de432822cf9 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 3fc5286082e73..aa6843f4a6d2b 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index e8c5e3b3a8327..9adda81297c71 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 742da0b7bfca5..dfd6c00ccaa4f 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index ba6ea78e2ca0d..0892ebe00a4af 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 67bb54d9bf4a7..6749a78383d90 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 5d1390c382f5f..dff452ed5ca6c 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index 00eb6d8971c0a..a8222c6f73a35 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 43de10c6224b9..d9a1f3701fe38 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index daf02df605db7..2ef27220a1c40 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 790e652c5603c..5d828552545c6 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 67c280d2eeaa9..fc4c19983ea80 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index a344b90a2f4ae..c87e28734802f 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index 398e3355b8610..6e114e8188c6b 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index c6d4d72f7d780..b353e88bd74f3 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 91479d9b5f8ca..fc673c59774c1 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index 422243dc06de2..a86a3e534b28d 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 39bf72758c217..bbecb363c4c0b 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index 788a14d6420f5..d9501d70b776d 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 380e1b3080ba6..1bcac30cc22c1 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index 9ce89b3b98b22..0c63383503aa8 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index e0a5e8371540e..0e1cbe2bd391b 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index 2cbad02d948b8..f9c8492587760 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index 4eb1bbccce1bc..86e604497ce85 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index c0605225415e2..1fb5ab2c0a2de 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 96fedeaf4c54c..83c342d60dbea 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index d2926fd658f34..77e07817d5895 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index e4f91889f4e9f..2c935765ea097 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index 9adc58f2fc685..2144f98fd58d5 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index 58ddc30ac84b9..3abf4bbe78ab3 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index a29a4ff22b499..d9e8b8af66924 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index 4bac0afd9d25f..785febc254310 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index 0c4f7f52b5a30..c3218ffa1fcd2 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index 7726b79aad379..8142a24c14ea0 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index e5fa63da7b23b..ece0bfda7c59c 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 1c35cd7694f6e..899dce7caf674 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index c5b9edf4fb589..4d13d0412addd 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 569e8ad2a5af6..d1cfa0d7e5e93 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index 20fd23405f1a0..728e2a7adab86 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 87413522a79eb..b4e10cc02478c 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 1398073968c9f..7ef35894ecaf9 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 1f3356b19495c..647b916fe560b 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index 38e60d02da6e1..5a32b074bd17b 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index c4da07bafeaf8..74788a1d1c89a 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index ee0d64be02fe8..e4da13b92e275 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index f5c4807976eed..8cd929feffec1 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 1c0a29740759b..233428680703f 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 61c55ba2567d5..bc9790cf70a50 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 5eaf16e278f9d..c1c3de99b4d47 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index 9d190c2833e16..6658dd54172ed 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index 3993e2f7e6ce7..7333352bd4b65 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index e49279f6cc307..810724ceca4bf 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index 9e0c25df23689..784f41aaa4b76 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index d94bee2a776f2..d72adf744eb98 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 698465332616e..e7ff61a0c624a 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 153025511ddd2..5c2f2a0557551 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index 7288d7de6d8c7..a636f200c9bea 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 0da07793a2099..ceb49813fad22 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index 208c004c106c5..a0376092022b2 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index ed28c5160fba7..4539dc7aa6b85 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index cba5333c4b71f..885b14f6806e4 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index 9081336b1c441..b70d56b389188 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 9d7bd2e57bf85..12775e6d70cae 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index ca510f938a1b6..9a0de2dab7a4b 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 897ff8cd6b8a9..25b206ca64627 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 255e093ee4a30..9e856adc8569b 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 384c946b80a7a..5694e12a7a9fc 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 48f85be23e0d8..4f723ae1661e6 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index 670dda82b079c..18a0dfb4aeead 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 6322400b7dd27..875ddb0081c96 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 22e7894678625..07cd55fc531ce 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index bfbef50ea9d21..0ef68983298bd 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 1e927b9d6395a..c8041592b14f9 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 54c2d9d0ef362..0a655ad808183 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 0a775b3472763..0757e0dceb14c 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index 482efde21091f..b7c63171a152d 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index cfc17dca605ad..b018b1732de98 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 4934a8e41ef9f..9b388a02d86cb 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 28ce9b060cd62..8f7e62fc55188 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index c2c4ab94edafe..2d17a8a632883 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 7c6908341d061..99e2db0f3160c 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 089e76188f6eb..54672c1714b13 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index c312898a268b1..77fea53183751 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 4c71118232b4e..a6bf5f990572c 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 89189f8e924a6..114a459b3752b 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 87672072d3ffe..3ee3d134dcf75 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index ad61125a94604..abf38d393c0b4 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index eae1a84873cdd..a89f4255c17ee 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index 622e612678b17..ce5979542650b 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index 510bf1b064e75..32cde58c6761e 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 9a781c01498a5..81bb74262835f 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index a0437a847aecd..2cb5705f96c47 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index 9c730cc4f160d..e9a9f78367f15 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index 858605305b68a..4f767fecb13d2 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index 54f95b7e0c24e..e6afbaff0894e 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index 6399e7d8e8a69..a3b4ed8f9caf5 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index 3671a5dda1223..2d1b0261a4e46 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index 743619d605cf8..c7b530611a172 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index 0fde065fdbfa5..e38ea0f4d2a21 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index e8d040be29770..e2839dfa0304f 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 0dcdf4c911fc8..fcd56da985b5b 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index bce5f42f61130..17aa748038269 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 0ac2a6ef50a00..fb5aca4efd734 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 5039e2d6851d1..026391b6489a8 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 78af350aa5e02..97d124ede683c 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index 1dd60257c2abf..10a594f474cb3 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 68575c074ef16..480582c9c0545 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index 7eede03c67cee..141fc7208768b 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index 20bcc82119765..3215f62423d07 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index 0361078a3def4..a637490c86a42 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index c37f10c4b8a43..dcd97d6c20ccd 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index d79cfcdb1bd15..43dccbd629075 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index 8a1f2ff327d7e..fb77719b003db 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index 419ba60fa98ee..b4fdc12475fa1 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 15e85910ddade..2dabb3198cedc 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index cf214ec5ea4cf..73053cd61cfb6 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 631bf32199376..4d69155a02948 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index 8afcde478e336..53a74ba6dd18b 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index e198f4919edf5..491ba1f9af335 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index f8c5e2be4b2a0..62c3cffc305fc 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 20ceb2ccd075c..07639400b0ad7 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index 6c165a6d49ed0..b7ba87842af49 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 16b07a9464525..343af9613a61d 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 97cf067aef9b2..79305962e8dcf 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index d38fa14a5033e..9c624d2380994 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 55aaa5b9e0f8f..7ae9a275e5b5d 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 565f08aeb6484..eca9ba76ef2f7 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 4c00118d8efce..7f3b985dbe059 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index c9e2bfb18c89f..35d572059c064 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 5966a4ad66ed6..d6ab9ab98811b 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index ce1e8b2145e40..e44107e495e30 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 9c109c3543365..c1d1de4a2cc04 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 7baa4f79bad7a..f063dac793e87 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 8e4713f092395..b368d6ec4e376 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index ca766ad9e5f8e..70d0db96c3311 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index bf2b7956baed7..5c3ddc31c90fc 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 0660386b2bc95..1212104b10bb7 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index d37b855985a98..4c13704fcd0ef 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index 6f5686de24bd0..4bdfc660a9a58 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 55718387c21d4..e7cae18b0eecc 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index ff7c81d96922d..72ceda2db5052 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index bdd3e1c5dd355..1cb6601c5db39 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 06a48b3521db4..075363f2e0493 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 309760d3dc9c3..8c2e7a5ea10cc 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 0c84033f1ba2d..af3b7fc437e7d 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index b464705b3805e..933eda3214780 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 1c34169f7a678..6bf1ac27b6a18 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 4a423d9f04350..16ee3e3135026 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index ca3a17b212147..7c52c43f688a9 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index e7b946b57668b..eb710a14eaa0c 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 9e6ec15925d00..b06b88ff69665 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index a82a67e24eed6..d6572e6a9c38d 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 3e230a7653c39..ff500acacf24d 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 8670a738e106e..f68a42a3f1a82 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index b4109301d5b55..25b32806db246 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index d7aca74817758..ba510fb321033 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index c95da1dc614df..b1b0cff46c80e 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index c5ad4831deb32..a5009bc5f8ab4 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index b6ee531e9af83..25e658d0cdea5 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index e1c8e4815a99e..2895b11aa7944 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index b6a2326cfe82c..4359363eadcee 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 25b3372bd7a9f..24f359134dabd 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 5aa1d602b6700..46a00d26058b7 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 0076733c05cdd..9ebbe4bbd0855 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -3060,6 +3060,40 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "observability", + "id": "def-public.SloEditLocatorParams", + "type": "Interface", + "tags": [], + "label": "SloEditLocatorParams", + "description": [], + "signature": [ + { + "pluginId": "observability", + "scope": "public", + "docId": "kibObservabilityPluginApi", + "section": "def-public.SloEditLocatorParams", + "text": "SloEditLocatorParams" + }, + " extends ", + "RecursivePartial", + "<", + "CreateSLOForm", + ">,", + { + "pluginId": "@kbn/utility-types", + "scope": "common", + "docId": "kibKbnUtilityTypesPluginApi", + "section": "def-common.SerializableRecord", + "text": "SerializableRecord" + } + ], + "path": "x-pack/plugins/observability/public/locators/slo_edit.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "initialIsOpen": false + }, { "parentPluginId": "observability", "id": "def-public.Stat", @@ -4078,6 +4112,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "observability", + "id": "def-public.sloEditLocatorID", + "type": "string", + "tags": [], + "label": "sloEditLocatorID", + "description": [], + "signature": [ + "\"SLO_EDIT_LOCATOR\"" + ], + "path": "x-pack/plugins/observability/common/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "observability", "id": "def-public.StringOrNull", @@ -4230,6 +4279,22 @@ }, "<", "SloDetailsLocatorParams", + ">; sloEditLocator: ", + { + "pluginId": "share", + "scope": "common", + "docId": "kibSharePluginApi", + "section": "def-common.LocatorPublic", + "text": "LocatorPublic" + }, + "<", + { + "pluginId": "observability", + "scope": "public", + "docId": "kibObservabilityPluginApi", + "section": "def-public.SloEditLocatorParams", + "text": "SloEditLocatorParams" + }, ">; getCoPilotService: () => ", "CoPilotService", "; }" @@ -7577,6 +7642,20 @@ "path": "x-pack/plugins/observability/server/routes/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.ObservabilityRouteHandlerResources.config", + "type": "Object", + "tags": [], + "label": "config", + "description": [], + "signature": [ + "{ readonly aiAssistant?: Readonly<{} & { enabled: boolean; feedback: Readonly<{} & { enabled: boolean; url: string; }>; provider: Readonly<{} & { openAI: Readonly<{} & { apiKey: string; model: string; }>; }> | Readonly<{} & { azureOpenAI: Readonly<{} & { apiKey: string; resourceName: string; deploymentId: string; }>; }>; }> | undefined; readonly enabled: boolean; readonly annotations: Readonly<{} & { index: string; enabled: boolean; }>; readonly unsafe: Readonly<{} & { alertDetails: Readonly<{} & { uptime: Readonly<{} & { enabled: boolean; }>; metrics: Readonly<{} & { enabled: boolean; }>; logs: Readonly<{} & { enabled: boolean; }>; }>; thresholdRule: Readonly<{} & { enabled: boolean; }>; }>; readonly thresholdRule: Readonly<{} & { groupByPageSize: number; }>; readonly compositeSlo: Readonly<{} & { enabled: boolean; }>; }" + ], + "path": "x-pack/plugins/observability/server/routes/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -7649,15 +7728,49 @@ "label": "ObservabilityAPIReturnType", "description": [], "signature": [ - "{ \"POST /internal/observability/copilot/prompts/profilingOptimizeFunction\": { endpoint: \"POST /internal/observability/copilot/prompts/profilingOptimizeFunction\"; params?: ", + "{ \"POST /internal/observability/copilot/prompts/{promptId}/track\": { endpoint: \"POST /internal/observability/copilot/prompts/{promptId}/track\"; params?: ", "TypeC", - "<{ body: ", + "<{ path: ", "TypeC", - "<{ library: ", + "<{ promptId: ", "StringC", - "; functionName: ", + "; }>; body: ", + "IntersectionC", + "<[", + "TypeC", + "<{ responseTime: ", + "NumberC", + "; messages: ", + "ArrayC", + "<", + "IntersectionC", + "<[", + "TypeC", + "<{ role: ", + "UnionC", + "<[", + "LiteralC", + "<\"system\">, ", + "LiteralC", + "<\"user\">, ", + "LiteralC", + "<\"assistant\">]>; content: ", "StringC", - "; }>; }> | undefined; handler: ({}: ", + "; }>, ", + "PartialC", + "<{ name: ", + "StringC", + "; }>]>>; response: ", + "StringC", + "; }>, ", + "PartialC", + "<{ feedbackAction: ", + "UnionC", + "<[", + "LiteralC", + "<\"thumbsup\">, ", + "LiteralC", + "<\"thumbsdown\">]>; }>]>; }> | undefined; handler: ({}: ", { "pluginId": "observability", "scope": "server", @@ -7665,7 +7778,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { body: { library: string; functionName: string; }; }; }) => Promise; } & ", + " & { params: { path: { promptId: string; }; body: { responseTime: number; messages: ({ role: \"user\" | \"system\" | \"assistant\"; content: string; } & { name?: string | undefined; })[]; response: string; } & { feedbackAction?: \"thumbsup\" | \"thumbsdown\" | undefined; }; }; }) => Promise; } & ", { "pluginId": "observability", "scope": "server", @@ -7673,7 +7786,7 @@ "section": "def-server.ObservabilityRouteCreateOptions", "text": "ObservabilityRouteCreateOptions" }, - "; \"POST /internal/observability/copilot/prompts/profilingExplainFunction\": { endpoint: \"POST /internal/observability/copilot/prompts/profilingExplainFunction\"; params?: ", + "; \"POST /internal/observability/copilot/prompts/profilingOptimizeFunction\": { endpoint: \"POST /internal/observability/copilot/prompts/profilingOptimizeFunction\"; params?: ", "TypeC", "<{ body: ", "TypeC", @@ -9468,7 +9581,7 @@ "label": "ObservabilityConfig", "description": [], "signature": [ - "{ readonly aiAssistant?: Readonly<{} & { enabled: boolean; provider: Readonly<{} & { openAI: Readonly<{} & { apiKey: string; model: string; }>; }> | Readonly<{} & { azureOpenAI: Readonly<{} & { apiKey: string; resourceName: string; deploymentId: string; }>; }>; }> | undefined; readonly enabled: boolean; readonly annotations: Readonly<{} & { index: string; enabled: boolean; }>; readonly unsafe: Readonly<{} & { alertDetails: Readonly<{} & { uptime: Readonly<{} & { enabled: boolean; }>; metrics: Readonly<{} & { enabled: boolean; }>; logs: Readonly<{} & { enabled: boolean; }>; }>; thresholdRule: Readonly<{} & { enabled: boolean; }>; }>; readonly thresholdRule: Readonly<{} & { groupByPageSize: number; }>; readonly compositeSlo: Readonly<{} & { enabled: boolean; }>; }" + "{ readonly aiAssistant?: Readonly<{} & { enabled: boolean; feedback: Readonly<{} & { enabled: boolean; url: string; }>; provider: Readonly<{} & { openAI: Readonly<{} & { apiKey: string; model: string; }>; }> | Readonly<{} & { azureOpenAI: Readonly<{} & { apiKey: string; resourceName: string; deploymentId: string; }>; }>; }> | undefined; readonly enabled: boolean; readonly annotations: Readonly<{} & { index: string; enabled: boolean; }>; readonly unsafe: Readonly<{} & { alertDetails: Readonly<{} & { uptime: Readonly<{} & { enabled: boolean; }>; metrics: Readonly<{} & { enabled: boolean; }>; logs: Readonly<{} & { enabled: boolean; }>; }>; thresholdRule: Readonly<{} & { enabled: boolean; }>; }>; readonly thresholdRule: Readonly<{} & { groupByPageSize: number; }>; readonly compositeSlo: Readonly<{} & { enabled: boolean; }>; }" ], "path": "x-pack/plugins/observability/server/index.ts", "deprecated": false, @@ -9483,15 +9596,49 @@ "label": "ObservabilityServerRouteRepository", "description": [], "signature": [ - "{ \"POST /internal/observability/copilot/prompts/profilingOptimizeFunction\": { endpoint: \"POST /internal/observability/copilot/prompts/profilingOptimizeFunction\"; params?: ", + "{ \"POST /internal/observability/copilot/prompts/{promptId}/track\": { endpoint: \"POST /internal/observability/copilot/prompts/{promptId}/track\"; params?: ", "TypeC", - "<{ body: ", + "<{ path: ", "TypeC", - "<{ library: ", + "<{ promptId: ", "StringC", - "; functionName: ", + "; }>; body: ", + "IntersectionC", + "<[", + "TypeC", + "<{ responseTime: ", + "NumberC", + "; messages: ", + "ArrayC", + "<", + "IntersectionC", + "<[", + "TypeC", + "<{ role: ", + "UnionC", + "<[", + "LiteralC", + "<\"system\">, ", + "LiteralC", + "<\"user\">, ", + "LiteralC", + "<\"assistant\">]>; content: ", "StringC", - "; }>; }> | undefined; handler: ({}: ", + "; }>, ", + "PartialC", + "<{ name: ", + "StringC", + "; }>]>>; response: ", + "StringC", + "; }>, ", + "PartialC", + "<{ feedbackAction: ", + "UnionC", + "<[", + "LiteralC", + "<\"thumbsup\">, ", + "LiteralC", + "<\"thumbsdown\">]>; }>]>; }> | undefined; handler: ({}: ", { "pluginId": "observability", "scope": "server", @@ -9499,7 +9646,7 @@ "section": "def-server.ObservabilityRouteHandlerResources", "text": "ObservabilityRouteHandlerResources" }, - " & { params: { body: { library: string; functionName: string; }; }; }) => Promise; } & ", + " & { params: { path: { promptId: string; }; body: { responseTime: number; messages: ({ role: \"user\" | \"system\" | \"assistant\"; content: string; } & { name?: string | undefined; })[]; response: string; } & { feedbackAction?: \"thumbsup\" | \"thumbsdown\" | undefined; }; }; }) => Promise; } & ", { "pluginId": "observability", "scope": "server", @@ -9507,7 +9654,7 @@ "section": "def-server.ObservabilityRouteCreateOptions", "text": "ObservabilityRouteCreateOptions" }, - "; \"POST /internal/observability/copilot/prompts/profilingExplainFunction\": { endpoint: \"POST /internal/observability/copilot/prompts/profilingExplainFunction\"; params?: ", + "; \"POST /internal/observability/copilot/prompts/profilingOptimizeFunction\": { endpoint: \"POST /internal/observability/copilot/prompts/profilingOptimizeFunction\"; params?: ", "TypeC", "<{ body: ", "TypeC", @@ -14273,6 +14420,117 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "observability", + "id": "def-common.loadCoPilotPrompts", + "type": "Function", + "tags": [], + "label": "loadCoPilotPrompts", + "description": [], + "signature": [ + "() => Promise<{ profilingOptimizeFunction: { params: ", + "TypeC", + "<{ library: ", + "StringC", + "; functionName: ", + "StringC", + "; }>; messages: (params: { library: string; functionName: string; }) => ", + "ChatCompletionRequestMessage", + "[]; }; apmExplainError: { params: ", + "IntersectionC", + "<[", + "TypeC", + "<{ serviceName: ", + "StringC", + "; languageName: ", + "StringC", + "; runtimeName: ", + "StringC", + "; runtimeVersion: ", + "StringC", + "; transactionName: ", + "StringC", + "; logStacktrace: ", + "StringC", + "; exceptionStacktrace: ", + "StringC", + "; }>, ", + "PartialC", + "<{ spanName: ", + "StringC", + "; }>]>; messages: (params: { serviceName: string; languageName: string; runtimeName: string; runtimeVersion: string; transactionName: string; logStacktrace: string; exceptionStacktrace: string; } & { spanName?: string | undefined; }) => ", + "ChatCompletionRequestMessage", + "[]; }; logsExplainMessage: { params: ", + "TypeC", + "<{ logEntry: ", + "TypeC", + "<{ fields: ", + "ArrayC", + "<", + "TypeC", + "<{ field: ", + "StringC", + "; value: ", + "ArrayC", + "<", + "AnyC", + ">; }>>; }>; }>; messages: (params: { logEntry: { fields: { field: string; value: any[]; }[]; }; }) => ", + "ChatCompletionRequestMessage", + "[]; }; logsFindSimilar: { params: ", + "TypeC", + "<{ logEntry: ", + "TypeC", + "<{ fields: ", + "ArrayC", + "<", + "TypeC", + "<{ field: ", + "StringC", + "; value: ", + "ArrayC", + "<", + "AnyC", + ">; }>>; }>; }>; messages: (params: { logEntry: { fields: { field: string; value: any[]; }[]; }; }) => ", + "ChatCompletionRequestMessage", + "[]; }; infraExplainProcess: { params: ", + "TypeC", + "<{ command: ", + "StringC", + "; }>; messages: (params: { command: string; }) => ", + "ChatCompletionRequestMessage", + "[]; }; explainLogSpike: { params: ", + "TypeC", + "<{ significantFieldValues: ", + "ArrayC", + "<", + "TypeC", + "<{ field: ", + "StringC", + "; value: ", + "UnionC", + "<[", + "StringC", + ", ", + "NumberC", + "]>; docCount: ", + "NumberC", + "; pValue: ", + "UnionC", + "<[", + "NumberC", + ", ", + "NullC", + "]>; }>>; }>; messages: (params: { significantFieldValues: { field: string; value: string | number; docCount: number; pValue: number | null; }[]; }) => ", + "ChatCompletionRequestMessage", + "[]; }; }>" + ], + "path": "x-pack/plugins/observability/common/co_pilot/index.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [ @@ -14395,7 +14653,7 @@ "tags": [], "label": "CoPilotPromptId", "description": [], - "path": "x-pack/plugins/observability/common/co_pilot.ts", + "path": "x-pack/plugins/observability/common/co_pilot/index.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -14911,6 +15169,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "observability", + "id": "def-common.sloEditLocatorID", + "type": "string", + "tags": [], + "label": "sloEditLocatorID", + "description": [], + "signature": [ + "\"SLO_EDIT_LOCATOR\"" + ], + "path": "x-pack/plugins/observability/common/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "observability", "id": "def-common.sloFeatureId", @@ -15200,221 +15473,6 @@ "initialIsOpen": false } ], - "objects": [ - { - "parentPluginId": "observability", - "id": "def-common.coPilotPrompts", - "type": "Object", - "tags": [], - "label": "coPilotPrompts", - "description": [], - "path": "x-pack/plugins/observability/common/co_pilot.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "observability", - "id": "def-common.coPilotPrompts.CoPilotPromptId.ProfilingOptimizeFunction", - "type": "Object", - "tags": [], - "label": "[CoPilotPromptId.ProfilingOptimizeFunction]", - "description": [], - "signature": [ - "{ params: ", - "TypeC", - "<{ library: ", - "StringC", - "; functionName: ", - "StringC", - "; }>; messages: (params: { library: string; functionName: string; }) => ", - "ChatCompletionRequestMessage", - "[]; }" - ], - "path": "x-pack/plugins/observability/common/co_pilot.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observability", - "id": "def-common.coPilotPrompts.CoPilotPromptId.ProfilingExplainFunction", - "type": "Object", - "tags": [], - "label": "[CoPilotPromptId.ProfilingExplainFunction]", - "description": [], - "signature": [ - "{ params: ", - "TypeC", - "<{ library: ", - "StringC", - "; functionName: ", - "StringC", - "; }>; messages: (params: { library: string; functionName: string; }) => ", - "ChatCompletionRequestMessage", - "[]; }" - ], - "path": "x-pack/plugins/observability/common/co_pilot.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observability", - "id": "def-common.coPilotPrompts.CoPilotPromptId.ApmExplainError", - "type": "Object", - "tags": [], - "label": "[CoPilotPromptId.ApmExplainError]", - "description": [], - "signature": [ - "{ params: ", - "IntersectionC", - "<[", - "TypeC", - "<{ serviceName: ", - "StringC", - "; languageName: ", - "StringC", - "; runtimeName: ", - "StringC", - "; runtimeVersion: ", - "StringC", - "; transactionName: ", - "StringC", - "; logStacktrace: ", - "StringC", - "; exceptionStacktrace: ", - "StringC", - "; }>, ", - "PartialC", - "<{ spanName: ", - "StringC", - "; }>]>; messages: (params: { serviceName: string; languageName: string; runtimeName: string; runtimeVersion: string; transactionName: string; logStacktrace: string; exceptionStacktrace: string; } & { spanName?: string | undefined; }) => ", - "ChatCompletionRequestMessage", - "[]; }" - ], - "path": "x-pack/plugins/observability/common/co_pilot.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observability", - "id": "def-common.coPilotPrompts.CoPilotPromptId.LogsExplainMessage", - "type": "Object", - "tags": [], - "label": "[CoPilotPromptId.LogsExplainMessage]", - "description": [], - "signature": [ - "{ params: ", - "TypeC", - "<{ logEntry: ", - "TypeC", - "<{ fields: ", - "ArrayC", - "<", - "TypeC", - "<{ field: ", - "StringC", - "; value: ", - "ArrayC", - "<", - "AnyC", - ">; }>>; }>; }>; messages: (params: { logEntry: { fields: { field: string; value: any[]; }[]; }; }) => ", - "ChatCompletionRequestMessage", - "[]; }" - ], - "path": "x-pack/plugins/observability/common/co_pilot.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observability", - "id": "def-common.coPilotPrompts.CoPilotPromptId.LogsFindSimilar", - "type": "Object", - "tags": [], - "label": "[CoPilotPromptId.LogsFindSimilar]", - "description": [], - "signature": [ - "{ params: ", - "TypeC", - "<{ logEntry: ", - "TypeC", - "<{ fields: ", - "ArrayC", - "<", - "TypeC", - "<{ field: ", - "StringC", - "; value: ", - "ArrayC", - "<", - "AnyC", - ">; }>>; }>; }>; messages: (params: { logEntry: { fields: { field: string; value: any[]; }[]; }; }) => ", - "ChatCompletionRequestMessage", - "[]; }" - ], - "path": "x-pack/plugins/observability/common/co_pilot.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observability", - "id": "def-common.coPilotPrompts.CoPilotPromptId.InfraExplainProcess", - "type": "Object", - "tags": [], - "label": "[CoPilotPromptId.InfraExplainProcess]", - "description": [], - "signature": [ - "{ params: ", - "TypeC", - "<{ command: ", - "StringC", - "; }>; messages: (params: { command: string; }) => ", - "ChatCompletionRequestMessage", - "[]; }" - ], - "path": "x-pack/plugins/observability/common/co_pilot.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "observability", - "id": "def-common.coPilotPrompts.CoPilotPromptId.ExplainLogSpike", - "type": "Object", - "tags": [], - "label": "[CoPilotPromptId.ExplainLogSpike]", - "description": [], - "signature": [ - "{ params: ", - "TypeC", - "<{ significantFieldValues: ", - "ArrayC", - "<", - "TypeC", - "<{ field: ", - "StringC", - "; value: ", - "UnionC", - "<[", - "StringC", - ", ", - "NumberC", - "]>; docCount: ", - "NumberC", - "; pValue: ", - "UnionC", - "<[", - "NumberC", - ", ", - "NullC", - "]>; }>>; }>; messages: (params: { significantFieldValues: { field: string; value: string | number; docCount: number; pValue: number | null; }[]; }) => ", - "ChatCompletionRequestMessage", - "[]; }" - ], - "path": "x-pack/plugins/observability/common/co_pilot.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - } - ] + "objects": [] } } \ No newline at end of file diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index fbc3508958587..f76c3118e482a 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/actionable-observability](https://github.com/orgs/elastic/team | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 526 | 45 | 518 | 18 | +| 523 | 45 | 515 | 19 | ## Client @@ -62,9 +62,6 @@ Contact [@elastic/actionable-observability](https://github.com/orgs/elastic/team ## Common -### Objects - - ### Functions diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index c78f74d6c882f..990ec4a27e661 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.devdocs.json b/api_docs/observability_shared.devdocs.json index 7b6ff8c06ed1c..2a32f416393dd 100644 --- a/api_docs/observability_shared.devdocs.json +++ b/api_docs/observability_shared.devdocs.json @@ -921,6 +921,39 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.TechnicalPreviewBadge", + "type": "Function", + "tags": [], + "label": "TechnicalPreviewBadge", + "description": [], + "signature": [ + "({ icon = 'beaker', size, style }: Props) => JSX.Element" + ], + "path": "x-pack/plugins/observability_shared/public/components/technical_preview_badge/technical_preview_badge.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "observabilityShared", + "id": "def-public.TechnicalPreviewBadge.$1", + "type": "CompoundType", + "tags": [], + "label": "{ icon = 'beaker', size, style }", + "description": [], + "signature": [ + "Props" + ], + "path": "x-pack/plugins/observability_shared/public/components/technical_preview_badge/technical_preview_badge.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "observabilityShared", "id": "def-public.useBreadcrumbs", diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index 2ce1737186d28..4d1731e7bd057 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/observability-ui](https://github.com/orgs/elastic/teams/observ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 266 | 1 | 265 | 11 | +| 268 | 1 | 267 | 11 | ## Client diff --git a/api_docs/osquery.devdocs.json b/api_docs/osquery.devdocs.json index 9b6da7eb49e58..d3d03ad153894 100644 --- a/api_docs/osquery.devdocs.json +++ b/api_docs/osquery.devdocs.json @@ -134,7 +134,7 @@ "LiveQueryQueryFieldProps", " & { formMethods: ", "UseFormReturn", - "<{ label: string; query: string; ecs_mapping: Record; }, any>; }) => JSX.Element) | undefined" + "<{ label: string; query: string; ecs_mapping: Record; }, any, undefined>; }) => JSX.Element) | undefined" ], "path": "x-pack/plugins/osquery/public/types.ts", "deprecated": false, diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index dd616dc2663f3..23e8f17609ec5 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 98e72930d470c..2087fa4505c69 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 71406 | 554 | 61219 | 1452 | +| 71411 | 554 | 61222 | 1455 | ## Plugin Directory @@ -70,7 +70,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 548 | 11 | 444 | 4 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 51 | 0 | 44 | 0 | -| | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 9 | 0 | 9 | 0 | +| | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 10 | 0 | 10 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 115 | 3 | 111 | 3 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | The Event Annotation service contains expressions for event annotations | 236 | 30 | 236 | 4 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 116 | 0 | 116 | 11 | @@ -94,7 +94,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 239 | 0 | 24 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Simple UI for managing files in Kibana | 2 | 1 | 2 | 0 | -| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1178 | 3 | 1062 | 38 | +| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1179 | 3 | 1063 | 39 | | ftrApis | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 0 | 0 | 0 | 0 | @@ -132,9 +132,9 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 34 | 0 | 34 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 1 | -| | [@elastic/actionable-observability](https://github.com/orgs/elastic/teams/actionable-observability) | - | 526 | 45 | 518 | 18 | +| | [@elastic/actionable-observability](https://github.com/orgs/elastic/teams/actionable-observability) | - | 523 | 45 | 515 | 19 | | | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | - | 7 | 0 | 7 | 0 | -| | [@elastic/observability-ui](https://github.com/orgs/elastic/teams/observability-ui) | - | 266 | 1 | 265 | 11 | +| | [@elastic/observability-ui](https://github.com/orgs/elastic/teams/observability-ui) | - | 268 | 1 | 267 | 11 | | | [@elastic/security-defend-workflows](https://github.com/orgs/elastic/teams/security-defend-workflows) | - | 24 | 0 | 24 | 7 | | painlessLab | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 218 | 8 | 164 | 11 | @@ -154,7 +154,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 32 | 0 | 13 | 0 | | | [@elastic/kibana-reporting-services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 8 | 5 | | searchprofiler | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | -| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 283 | 0 | 94 | 1 | +| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 287 | 0 | 96 | 2 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 176 | 2 | 132 | 30 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | ESS customizations for Security Solution. | 6 | 0 | 6 | 0 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | Serverless customizations for security. | 6 | 0 | 6 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 306d81a66c57c..49f0c03deeef3 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 10bf8465201bc..c8405b2fe7624 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 8fc007f26d583..061a36c113752 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 708ac22b536eb..dddc7f18da556 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/reporting_export_types.mdx b/api_docs/reporting_export_types.mdx index 6b9e8c088933c..16234f5dcfed5 100644 --- a/api_docs/reporting_export_types.mdx +++ b/api_docs/reporting_export_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reportingExportTypes title: "reportingExportTypes" image: https://source.unsplash.com/400x175/?github description: API docs for the reportingExportTypes plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reportingExportTypes'] --- import reportingExportTypesObj from './reporting_export_types.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 55aaf7fb49561..0a3db73eafdf9 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index b2e08dbfc5ae8..61515ec3d047e 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index bf5d42ca09b5a..2342963090b61 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index a415a7115c42f..03793085a0211 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index 8ee7adf6c6294..4f598934611c0 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 1cd3c19ccf1a0..223c08a8743e6 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 0e0cbc78e84a7..e6407d095fc21 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 2d1d73970d0aa..d1897434ad5c0 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index dc3a6d2e7062f..ac1c308212638 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 9ce5e1a764c9a..5032c2b053104 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 3336908f92a4b..4b818560f503b 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.devdocs.json b/api_docs/security.devdocs.json index 2637d8ad0cf48..7dc64bd48e25f 100644 --- a/api_docs/security.devdocs.json +++ b/api_docs/security.devdocs.json @@ -799,6 +799,22 @@ "path": "x-pack/plugins/security/public/nav_control/nav_control_component.tsx", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "security", + "id": "def-public.UserMenuLink.content", + "type": "CompoundType", + "tags": [], + "label": "content", + "description": [ + "Render a custom ReactNode instead of the default " + ], + "signature": [ + "boolean | React.ReactChild | React.ReactFragment | React.ReactPortal | null | undefined" + ], + "path": "x-pack/plugins/security/public/nav_control/nav_control_component.tsx", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -983,6 +999,42 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false + }, + { + "parentPluginId": "security", + "id": "def-public.UpdateUserProfileHook", + "type": "Type", + "tags": [], + "label": "UpdateUserProfileHook", + "description": [], + "signature": [ + "(props?: Props | undefined) => { update: (data: ", + "UserProfileData", + ") => void; showSuccessNotification: (props: { isRefreshRequired: boolean; }) => void; isLoading: boolean; userProfileData?: ", + "UserProfileData", + " | null | undefined; }" + ], + "path": "x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "security", + "id": "def-public.UpdateUserProfileHook.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "Props | undefined" + ], + "path": "x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false } ], "objects": [], @@ -1110,14 +1162,10 @@ "\nA set of methods to work with Kibana user profiles." ], "signature": [ - "{ suggest: (data: D) => Promise; suggest: (path: string, params: ", { "pluginId": "security", @@ -1135,13 +1183,7 @@ "text": "UserProfile" }, "[]>; bulkGet: (params: ", { "pluginId": "security", @@ -1159,13 +1201,7 @@ "text": "UserProfile" }, "[]>; getCurrent: (params?: ", { "pluginId": "security", @@ -1182,7 +1218,35 @@ "section": "def-common.GetUserProfileResponse", "text": "GetUserProfileResponse" }, - ">; }" + ">; readonly userProfile$: ", + "Observable", + "<", + "UserProfileData", + " | null>; }" + ], + "path": "x-pack/plugins/security/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "security", + "id": "def-public.SecurityPluginStart.hooks", + "type": "Object", + "tags": [], + "label": "hooks", + "description": [ + "\nA set of hooks to work with Kibana user profiles" + ], + "signature": [ + "{ useUpdateUserProfile: ", + { + "pluginId": "security", + "scope": "public", + "docId": "kibSecurityPluginApi", + "section": "def-public.UpdateUserProfileHook", + "text": "UpdateUserProfileHook" + }, + "; }" ], "path": "x-pack/plugins/security/public/plugin.tsx", "deprecated": false, diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 93c3c34ab3f3a..3c50b8d179486 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 283 | 0 | 94 | 1 | +| 287 | 0 | 96 | 2 | ## Client diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 12c96b0489eb1..77d36124df657 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index 4b075c96b93cb..1b7fce653f9f7 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index c0bd2276b506b..c9337918d58a6 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 3857f83fd5316..d40fc8030bf48 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index 2325827a0fde5..d82d3853bce7e 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index acdbb7fafc901..a12f9ba939189 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 01bb14d46455d..b6ca98f304703 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 6fa1e15cdece0..fb892b7ebdfc9 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 80b510f41a538..42591a87924c2 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 31ca31cdf0b20..2c94c5d9f6563 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index e943e0ef99c01..c213ec844b5c6 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index 185c1e9e6751f..8c57463b3e055 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 1926397632e90..061c24ef96aab 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index ae3107d151d7b..3f2282a2ffdfb 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 2850f28186151..49e31055ef1a5 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index fb60260dcb0f9..2b84aa0283f5c 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 21619a7e4f452..fb01126495d91 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 6d1497a9e8467..bcadda5438b28 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index add2781d01761..12787cbd4c58d 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 5914d96331826..973b24abe99c0 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 4c89c62e6ea5d..e4c4abf691016 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 0a369a01c2498..1792595ad4f40 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 2d8318890a7b2..dce96e9772ddd 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index ea028e5eeada3..17921994ae1bb 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 6a7ff22ae4abb..9e5b5727e1bf2 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 9231e118ab54c..3e9167cd28b7f 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 953b50622412e..8017ee0e95482 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index d8e713cc228e5..8b100c53b3ff9 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index e53c2069d942a..dedf029870088 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 8f82b0dc42e40..2e99c7ee0c07d 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 80f9a0ec49405..c0c55190c4e05 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 120b8cc82afb2..cbfcac5112433 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 2102f45d75182..df168319a6c13 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 5fe96186f9f78..73460fcfec095 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 562d6530b7256..386fa54ce0052 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 125994d58e028..ab870cd028706 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index 53fa9cca7b44e..e023f80fd1104 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index e2a3e5465f526..19138351e80eb 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 65693b98df616..c7fb5de6aa6f0 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index a7b12e70a4b31..3680e6bab24c7 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualization_ui_components.mdx b/api_docs/visualization_ui_components.mdx index f9d8116aa5a56..ec276480b309e 100644 --- a/api_docs/visualization_ui_components.mdx +++ b/api_docs/visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizationUiComponents title: "visualizationUiComponents" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizationUiComponents plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizationUiComponents'] --- import visualizationUiComponentsObj from './visualization_ui_components.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 435359ae605d9..12793958e55cc 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-07-12 +date: 2023-07-13 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 7c333cdc33fe974292c463bec94c3fa75630c31a Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Thu, 13 Jul 2023 07:27:13 +0200 Subject: [PATCH 89/97] [Index Management] Disable certain actions for serverless (#161528) --- config/serverless.yml | 3 ++ .../test_suites/core_plugins/rendering.ts | 1 + .../home/indices_tab.test.ts | 8 +++-- .../__jest__/components/index_table.test.js | 31 +++++++++++++++++-- .../public/application/app_context.tsx | 3 +- .../application/mount_management_section.ts | 4 ++- .../index_actions_context_menu.js | 12 ++++--- .../plugins/index_management/public/plugin.ts | 4 ++- .../plugins/index_management/public/types.ts | 1 + .../plugins/index_management/server/config.ts | 2 ++ 10 files changed, 58 insertions(+), 11 deletions(-) diff --git a/config/serverless.yml b/config/serverless.yml index 5f03bbb6de504..ea2d93a5d3c48 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -36,6 +36,9 @@ xpack.remote_clusters.enabled: false xpack.snapshot_restore.enabled: false xpack.license_management.enabled: false +# Disable index management actions from the UI +xpack.index_management.enableIndexActions: false + # Keep deeplinks visible so that they are shown in the sidenav dev_tools.deeplinks.navLinkStatus: visible management.deeplinks.navLinkStatus: visible diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 7a3b22d62712c..d9f6a4764319b 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -232,6 +232,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.graph.savePolicy (alternatives)', 'xpack.ilm.ui.enabled (boolean)', 'xpack.index_management.ui.enabled (boolean)', + 'xpack.index_management.enableIndexActions (boolean)', 'xpack.infra.sources.default.fields.message (array)', /** * xpack.infra.logs is conditional and will resolve to an object of properties diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts index d5eb4eb1fed7a..8b2b1d6568253 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts @@ -225,7 +225,9 @@ describe('', () => { ]); httpRequestsMockHelpers.setReloadIndicesResponse({ indexNames: [indexNameA, indexNameB] }); - testBed = await setup(httpSetup); + testBed = await setup(httpSetup, { + enableIndexActions: true, + }); const { component, find } = testBed; component.update(); @@ -268,7 +270,9 @@ describe('', () => { }); test('should be able to open a closed index', async () => { - testBed = await setup(httpSetup); + testBed = await setup(httpSetup, { + enableIndexActions: true, + }); const { component, find, actions } = testBed; component.update(); diff --git a/x-pack/plugins/index_management/__jest__/components/index_table.test.js b/x-pack/plugins/index_management/__jest__/components/index_table.test.js index c751402d3c711..ad704311dd210 100644 --- a/x-pack/plugins/index_management/__jest__/components/index_table.test.js +++ b/x-pack/plugins/index_management/__jest__/components/index_table.test.js @@ -144,7 +144,7 @@ const getActionMenuButtons = (rendered) => { describe('index table', () => { const { httpSetup, httpRequestsMockHelpers } = initHttpRequests(); - beforeEach(() => { + const setupMockComponent = (dependenciesOverride) => { // Mock initialization of services const services = { extensionsService: new ExtensionsService(), @@ -168,12 +168,13 @@ describe('index table', () => { }, plugins: {}, url: urlServiceMock, + enableIndexActions: true, }; component = ( - + @@ -181,6 +182,11 @@ describe('index table', () => { ); store.dispatch(loadIndicesSuccess({ indices })); + }; + + beforeEach(() => { + // Mock initialization of services + setupMockComponent(); httpRequestsMockHelpers.setLoadIndicesResponse(indices); httpRequestsMockHelpers.setReloadIndicesResponse(indices); @@ -506,4 +512,25 @@ describe('index table', () => { rendered.update(); testEditor(rendered, 'editIndexMenuButton'); }); + + describe('Common index actions', () => { + beforeEach(() => { + // Mock initialization of services + setupMockComponent({ enableIndexActions: false }); + }); + + test('Common index actions should be hidden when feature is turned off', async () => { + const rendered = mountWithIntl(component); + await runAllPromises(); + rendered.update(); + + expect(findTestSubject(rendered, 'showStatsIndexMenuButton').length).toBe(0); + expect(findTestSubject(rendered, 'closeIndexMenuButton').length).toBe(0); + expect(findTestSubject(rendered, 'forcemergeIndexMenuButton').length).toBe(0); + expect(findTestSubject(rendered, 'refreshIndexMenuButton').length).toBe(0); + expect(findTestSubject(rendered, 'clearCacheIndexMenuButton').length).toBe(0); + expect(findTestSubject(rendered, 'flushIndexMenuButton').length).toBe(0); + expect(findTestSubject(rendered, 'unfreezeIndexMenuButton').length).toBe(0); + }); + }); }); diff --git a/x-pack/plugins/index_management/public/application/app_context.tsx b/x-pack/plugins/index_management/public/application/app_context.tsx index 968f432900faa..9acbda3f9685f 100644 --- a/x-pack/plugins/index_management/public/application/app_context.tsx +++ b/x-pack/plugins/index_management/public/application/app_context.tsx @@ -25,7 +25,7 @@ import type { SettingsStart } from '@kbn/core-ui-settings-browser'; import { ExtensionsService } from '../services'; import { UiMetricService, NotificationService, HttpService } from './services'; -const AppContext = createContext(undefined); +export const AppContext = createContext(undefined); export interface AppDependencies { core: { @@ -52,6 +52,7 @@ export interface AppDependencies { docLinks: DocLinksStart; kibanaVersion: SemVer; theme$: Observable; + enableIndexActions: boolean; } export const AppContextProvider = ({ diff --git a/x-pack/plugins/index_management/public/application/mount_management_section.ts b/x-pack/plugins/index_management/public/application/mount_management_section.ts index 1690afb504a5c..d00aa6ff1f0e6 100644 --- a/x-pack/plugins/index_management/public/application/mount_management_section.ts +++ b/x-pack/plugins/index_management/public/application/mount_management_section.ts @@ -52,7 +52,8 @@ export async function mountManagementSection( params: ManagementAppMountParams, extensionsService: ExtensionsService, isFleetEnabled: boolean, - kibanaVersion: SemVer + kibanaVersion: SemVer, + enableIndexActions: boolean ) { const { element, setBreadcrumbs, history, theme$ } = params; const [core, startDependencies] = await coreSetup.getStartServices(); @@ -94,6 +95,7 @@ export async function mountManagementSection( uiMetricService, extensionsService, }, + enableIndexActions, history, setBreadcrumbs, uiSettings, diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js index 54d1752734e01..4188797431e5d 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js @@ -25,9 +25,11 @@ import { import { flattenPanelTree } from '../../../../lib/flatten_panel_tree'; import { INDEX_OPEN } from '../../../../../../common/constants'; -import { AppContextConsumer } from '../../../../app_context'; +import { AppContextConsumer, AppContext } from '../../../../app_context'; export class IndexActionsContextMenu extends Component { + static contextType = AppContext; + constructor(props) { super(props); @@ -47,6 +49,8 @@ export class IndexActionsContextMenu extends Component { this.setState({ isActionConfirmed }); }; panels({ services: { extensionsService }, core: { getUrlForApp } }) { + const { enableIndexActions } = this.context; + const { closeIndices, openIndices, @@ -94,7 +98,7 @@ export class IndexActionsContextMenu extends Component { this.closePopoverAndExecute(showMapping); }, }); - if (allOpen) { + if (allOpen && enableIndexActions) { items.push({ 'data-test-subj': 'showStatsIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.showIndexStatsLabel', { @@ -118,7 +122,7 @@ export class IndexActionsContextMenu extends Component { }, }); } - if (allOpen) { + if (allOpen && enableIndexActions) { items.push({ 'data-test-subj': 'closeIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.closeIndexLabel', { @@ -187,7 +191,7 @@ export class IndexActionsContextMenu extends Component { }, }); } - } else { + } else if (!allOpen && enableIndexActions) { items.push({ 'data-test-subj': 'openIndexMenuButton', name: i18n.translate('xpack.idxMgmt.indexActionsMenu.openIndexLabel', { diff --git a/x-pack/plugins/index_management/public/plugin.ts b/x-pack/plugins/index_management/public/plugin.ts index a63ee693aa19f..fc965a061e0bf 100644 --- a/x-pack/plugins/index_management/public/plugin.ts +++ b/x-pack/plugins/index_management/public/plugin.ts @@ -38,6 +38,7 @@ export class IndexMgmtUIPlugin { ): IndexManagementPluginSetup { const { ui: { enabled: isIndexManagementUiEnabled }, + enableIndexActions, } = this.ctx.config.get(); if (isIndexManagementUiEnabled) { @@ -55,7 +56,8 @@ export class IndexMgmtUIPlugin { params, this.extensionsService, Boolean(fleet), - kibanaVersion + kibanaVersion, + enableIndexActions ); }, }); diff --git a/x-pack/plugins/index_management/public/types.ts b/x-pack/plugins/index_management/public/types.ts index 57c7e11b6262b..59954c6659494 100644 --- a/x-pack/plugins/index_management/public/types.ts +++ b/x-pack/plugins/index_management/public/types.ts @@ -28,4 +28,5 @@ export interface ClientConfigType { ui: { enabled: boolean; }; + enableIndexActions: boolean; } diff --git a/x-pack/plugins/index_management/server/config.ts b/x-pack/plugins/index_management/server/config.ts index 157d6d3da8737..4fd24bf3fcdf7 100644 --- a/x-pack/plugins/index_management/server/config.ts +++ b/x-pack/plugins/index_management/server/config.ts @@ -22,6 +22,7 @@ const schemaLatest = schema.object( ui: schema.object({ enabled: schema.boolean({ defaultValue: true }), }), + enableIndexActions: schema.boolean({ defaultValue: true }), }, { defaultValue: undefined } ); @@ -29,6 +30,7 @@ const schemaLatest = schema.object( const configLatest: PluginConfigDescriptor = { exposeToBrowser: { ui: true, + enableIndexActions: true, }, schema: schemaLatest, deprecations: () => [], From ac4635417f92373b924eb360a264869d69f35950 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Thu, 13 Jul 2023 09:26:50 +0200 Subject: [PATCH 90/97] [AO] Fix showing temporary data view in the list of data views for the new threshold rule (#161462) Closes #159774, closes #159778, closes #159779, closes #159776 ## Summary This PR fixes the data view list in the new metric threshold. Also, it adds an API integration test to check the reference in the rule saved object. Also, this PR improves the error handling and loading of the data view, similar to what we have for elasticsearch rule data view. |Threshold rule error|Elasticsearch query error| |---|---| |![image](https://github.com/elastic/kibana/assets/12370520/ae5ff9bb-8bcc-46d2-8b84-42f7128f18e1)|![image](https://github.com/elastic/kibana/assets/12370520/1f65ff6b-18f3-4a4d-941b-cafe35c4d145)| ## How to test - Make sure `xpack.observability.unsafe.thresholdRule.enabled` is set to true in kibana yml config Error handling - Throw an error [here](https://github.com/elastic/kibana/pull/161462/files#diff-4f65f6debaf6457d4b0400a27c1ea57ba52bfe4426ee40460d43a857c5bd165eL98) and make sure the message is shown correctly in the rule. Temporary data view - Create a temporary data view - Check the list of data views and make sure the new temporary one is added to the list |Adding a new temporary data view|Temporary data view in the list| |---|---| |![image](https://github.com/elastic/kibana/assets/12370520/5f0866b6-34ad-4072-9a84-48e0760072d6)|![image](https://github.com/elastic/kibana/assets/12370520/9109308e-88d4-49f7-98b1-19f635804c48)| --- ...tsx => threshold_rule_expression.test.tsx} | 56 ++++++-- ...sion.tsx => threshold_rule_expression.tsx} | 52 +++++-- .../observability/public/plugin.mock.tsx | 4 +- .../register_observability_rule_types.ts | 2 +- .../observability/index.ts | 1 + .../observability/threshold_rule.ts | 6 - .../observability/threshold_rule_data_view.ts | 136 ++++++++++++++++++ 7 files changed, 228 insertions(+), 29 deletions(-) rename x-pack/plugins/observability/public/components/threshold/{components/expression.test.tsx => threshold_rule_expression.test.tsx} (64%) rename x-pack/plugins/observability/public/components/threshold/{components/expression.tsx => threshold_rule_expression.tsx} (94%) create mode 100644 x-pack/test/alerting_api_integration/observability/threshold_rule_data_view.ts diff --git a/x-pack/plugins/observability/public/components/threshold/components/expression.test.tsx b/x-pack/plugins/observability/public/components/threshold/threshold_rule_expression.test.tsx similarity index 64% rename from x-pack/plugins/observability/public/components/threshold/components/expression.test.tsx rename to x-pack/plugins/observability/public/components/threshold/threshold_rule_expression.test.tsx index 692ffc9539ab2..6de8d9efde686 100644 --- a/x-pack/plugins/observability/public/components/threshold/components/expression.test.tsx +++ b/x-pack/plugins/observability/public/components/threshold/threshold_rule_expression.test.tsx @@ -5,18 +5,18 @@ * 2.0. */ -import { useKibana } from '../../../utils/kibana_react'; -import { kibanaStartMock } from '../../../utils/kibana_react.mock'; -import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers'; import React from 'react'; import { act } from 'react-dom/test-utils'; - -import Expressions from './expression'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; -import { MetricsExplorerMetric } from '../../../../common/threshold_rule/metrics_explorer'; -import { Comparator } from '../../../../common/threshold_rule/types'; +import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers'; + +import { Comparator } from '../../../common/threshold_rule/types'; +import { MetricsExplorerMetric } from '../../../common/threshold_rule/metrics_explorer'; +import { useKibana } from '../../utils/kibana_react'; +import { kibanaStartMock } from '../../utils/kibana_react.mock'; +import Expressions from './threshold_rule_expression'; -jest.mock('../../../utils/kibana_react'); +jest.mock('../../utils/kibana_react'); const useKibanaMock = useKibana as jest.Mock; @@ -106,4 +106,44 @@ describe('Expression', () => { }, ]); }); + + it('should show the error message', async () => { + const currentOptions = { + groupBy: 'host.hostname', + filterQuery: 'foo', + metrics: [ + { aggregation: 'avg', field: 'system.load.1' }, + { aggregation: 'cardinality', field: 'system.cpu.user.pct' }, + ] as MetricsExplorerMetric[], + }; + const errorMessage = 'Error in searchSource create'; + const kibanaMock = kibanaStartMock.startContract(); + useKibanaMock.mockReturnValue({ + ...kibanaMock, + services: { + ...kibanaMock.services, + data: { + dataViews: { + create: jest.fn(), + }, + query: { + timefilter: { + timefilter: jest.fn(), + }, + }, + search: { + searchSource: { + create: jest.fn(() => { + throw new Error(errorMessage); + }), + }, + }, + }, + }, + }); + const { wrapper } = await setup(currentOptions); + expect(wrapper.find(`[data-test-subj="thresholdRuleExpressionError"]`).first().text()).toBe( + errorMessage + ); + }); }); diff --git a/x-pack/plugins/observability/public/components/threshold/components/expression.tsx b/x-pack/plugins/observability/public/components/threshold/threshold_rule_expression.tsx similarity index 94% rename from x-pack/plugins/observability/public/components/threshold/components/expression.tsx rename to x-pack/plugins/observability/public/components/threshold/threshold_rule_expression.tsx index 703b30fe64519..50deb2ad0fb92 100644 --- a/x-pack/plugins/observability/public/components/threshold/components/expression.tsx +++ b/x-pack/plugins/observability/public/components/threshold/threshold_rule_expression.tsx @@ -6,14 +6,18 @@ */ import React, { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react'; +import { debounce } from 'lodash'; import { EuiAccordion, EuiButtonEmpty, + EuiCallOut, EuiCheckbox, + EuiEmptyPrompt, EuiFieldSearch, EuiFormRow, EuiIcon, EuiLink, + EuiLoadingSpinner, EuiPanel, EuiSpacer, EuiText, @@ -25,23 +29,24 @@ import { DataViewBase } from '@kbn/es-query'; import { DataViewSelectPopover } from '@kbn/stack-alerts-plugin/public'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { debounce } from 'lodash'; import { ForLastExpression, IErrorObject, RuleTypeParams, RuleTypeParamsExpressionProps, } from '@kbn/triggers-actions-ui-plugin/public'; -import { useKibana } from '../../../utils/kibana_react'; -import { Aggregators, Comparator, QUERY_INVALID } from '../../../../common/threshold_rule/types'; -import { TimeUnitChar } from '../../../../common/utils/formatters/duration'; -import { AlertContextMeta, AlertParams, MetricExpression } from '../types'; -import { ExpressionChart } from './expression_chart'; -import { ExpressionRow } from './expression_row'; -import { MetricsExplorerKueryBar } from './kuery_bar'; -import { MetricsExplorerOptions } from '../hooks/use_metrics_explorer_options'; -import { convertKueryToElasticSearchQuery } from '../helpers/kuery'; -import { MetricsExplorerGroupBy } from './group_by'; + +import { useKibana } from '../../utils/kibana_react'; +import { Aggregators, Comparator, QUERY_INVALID } from '../../../common/threshold_rule/types'; +import { TimeUnitChar } from '../../../common/utils/formatters/duration'; +import { AlertContextMeta, AlertParams, MetricExpression } from './types'; +import { ExpressionChart } from './components/expression_chart'; +import { ExpressionRow } from './components/expression_row'; +import { MetricsExplorerKueryBar } from './components/kuery_bar'; +import { MetricsExplorerGroupBy } from './components/group_by'; +import { MetricsExplorerOptions } from './hooks/use_metrics_explorer_options'; +import { convertKueryToElasticSearchQuery } from './helpers/kuery'; + const FILTER_TYPING_DEBOUNCE_MS = 500; type Props = Omit< @@ -66,6 +71,7 @@ export default function Expressions(props: Props) { const [timeUnit, setTimeUnit] = useState('m'); const [dataView, setDataView] = useState(); const [searchSource, setSearchSource] = useState(); + const [paramsError, setParamsError] = useState(); const derivedIndexPattern = useMemo( () => ({ fields: dataView?.fields || [], @@ -97,8 +103,7 @@ export default function Expressions(props: Props) { setSearchSource(createdSearchSource); setDataView(createdSearchSource.getField('index')); } catch (error) { - // TODO Handle error - console.log('error:', error); + setParamsError(error); } }; @@ -335,11 +340,32 @@ export default function Expressions(props: Props) { .filter((g) => typeof g === 'string') as string[]; }, [ruleParams, groupByFilterTestPatterns]); + if (paramsError) { + return ( + <> + +

{paramsError.message}

+
+ + + ); + } + + if (!searchSource) { + return ( + <> + } /> + + + ); + } + return ( <> { onChangeMetaData({ ...metadata, adHocDataViewList }); diff --git a/x-pack/plugins/observability/public/plugin.mock.tsx b/x-pack/plugins/observability/public/plugin.mock.tsx index aa847fd198cf4..bfd5eb973004e 100644 --- a/x-pack/plugins/observability/public/plugin.mock.tsx +++ b/x-pack/plugins/observability/public/plugin.mock.tsx @@ -72,7 +72,9 @@ const data = { }, }, search: { - searchSource: jest.fn(), + searchSource: { + create: jest.fn(), + }, }, }; }, diff --git a/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts b/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts index 8e28412050920..8fade4abf38f4 100644 --- a/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts +++ b/x-pack/plugins/observability/public/rules/register_observability_rule_types.ts @@ -93,7 +93,7 @@ export const registerObservabilityRuleTypes = ( documentationUrl(docLinks) { return `${docLinks.links.observability.threshold}`; }, - ruleParamsExpression: lazy(() => import('../components/threshold/components/expression')), + ruleParamsExpression: lazy(() => import('../components/threshold/threshold_rule_expression')), validate: validateMetricThreshold, defaultActionMessage: i18n.translate( 'xpack.observability.threshold.rule.alerting.threshold.defaultActionMessage', diff --git a/x-pack/test/alerting_api_integration/observability/index.ts b/x-pack/test/alerting_api_integration/observability/index.ts index a5f284cbffeda..c3fb33202ce9e 100644 --- a/x-pack/test/alerting_api_integration/observability/index.ts +++ b/x-pack/test/alerting_api_integration/observability/index.ts @@ -11,6 +11,7 @@ export default function ({ loadTestFile }: any) { describe('MetricsUI Endpoints', () => { loadTestFile(require.resolve('./metric_threshold_rule')); loadTestFile(require.resolve('./threshold_rule')); + loadTestFile(require.resolve('./threshold_rule_data_view')); }); describe('Synthetics', () => { diff --git a/x-pack/test/alerting_api_integration/observability/threshold_rule.ts b/x-pack/test/alerting_api_integration/observability/threshold_rule.ts index ab1907f951745..0d2ac7556147e 100644 --- a/x-pack/test/alerting_api_integration/observability/threshold_rule.ts +++ b/x-pack/test/alerting_api_integration/observability/threshold_rule.ts @@ -4,12 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ import moment from 'moment'; import { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; diff --git a/x-pack/test/alerting_api_integration/observability/threshold_rule_data_view.ts b/x-pack/test/alerting_api_integration/observability/threshold_rule_data_view.ts new file mode 100644 index 0000000000000..ba846751ef7b4 --- /dev/null +++ b/x-pack/test/alerting_api_integration/observability/threshold_rule_data_view.ts @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { Aggregators, Comparator } from '@kbn/observability-plugin/common/threshold_rule/types'; +import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/observability-plugin/common/constants'; + +import { FtrProviderContext } from '../common/ftr_provider_context'; +import { getUrlPrefix, ObjectRemover } from '../common/lib'; +import { createRule } from './helpers/alerting_api_helper'; +import { createDataView, deleteDataView } from './helpers/data_view'; + +// eslint-disable-next-line import/no-default-export +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const objectRemover = new ObjectRemover(supertest); + const es = getService('es'); + + describe('Threshold rule data view >', () => { + const DATA_VIEW_ID = 'data-view-id'; + + let ruleId: string; + + const searchRule = () => + es.search<{ references: unknown; alert: { params: any } }>({ + index: '.kibana*', + query: { + bool: { + filter: [ + { + term: { + _id: `alert:${ruleId}`, + }, + }, + ], + }, + }, + fields: ['alert.params', 'references'], + }); + + before(async () => { + await createDataView({ + supertest, + name: 'test-data-view', + id: DATA_VIEW_ID, + title: 'random-index*', + }); + }); + + after(async () => { + objectRemover.removeAll(); + await deleteDataView({ + supertest, + id: DATA_VIEW_ID, + }); + }); + + describe('save data view in rule correctly', () => { + it('create a threshold rule', async () => { + const createdRule = await createRule({ + supertest, + tags: ['observability'], + consumer: 'alerts', + name: 'Threshold rule', + ruleTypeId: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + params: { + criteria: [ + { + aggType: Aggregators.CUSTOM, + comparator: Comparator.GT, + threshold: [7500000], + timeSize: 5, + timeUnit: 'm', + customMetrics: [ + { name: 'A', field: 'span.self_time.sum.us', aggType: Aggregators.AVERAGE }, + ], + }, + ], + alertOnNoData: true, + alertOnGroupDisappear: true, + searchConfiguration: { + query: { + query: '', + language: 'kuery', + }, + index: DATA_VIEW_ID, + }, + }, + actions: [], + }); + ruleId = createdRule.id; + expect(ruleId).not.to.be(undefined); + }); + + it('should have correct data view reference before and after edit', async () => { + const { + hits: { hits: alertHitsV1 }, + } = await searchRule(); + + await supertest + .post(`${getUrlPrefix('default')}/internal/alerting/rules/_bulk_edit`) + .set('kbn-xsrf', 'foo') + .send({ + ids: [ruleId], + operations: [{ operation: 'set', field: 'apiKey' }], + }) + .expect(200); + objectRemover.add('default', ruleId, 'rule', 'alerting'); + + const { + hits: { hits: alertHitsV2 }, + } = await searchRule(); + + expect(alertHitsV1[0]?._source?.references).to.eql([ + { + name: 'param:kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: 'data-view-id', + }, + ]); + expect(alertHitsV1[0]?._source?.alert?.params?.searchConfiguration).to.eql({ + query: { query: '', language: 'kuery' }, + indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index', + }); + expect(alertHitsV1[0].fields).to.eql(alertHitsV2[0].fields); + expect(alertHitsV1[0]?._source?.references ?? true).to.eql( + alertHitsV2[0]?._source?.references ?? false + ); + }); + }); + }); +} From 88d45238f92c8aa32a7e85296793df89bc689e57 Mon Sep 17 00:00:00 2001 From: Jill Guyonnet Date: Thu, 13 Jul 2023 09:58:01 +0200 Subject: [PATCH 91/97] [Fleet] Fix GET /package_policies schema (#161774) ## Summary Followup fix to https://github.com/elastic/kibana/pull/160921/files. In the above PR, I had flagged the following issue: ![Screenshot 2023-07-12 at 16 46 01](https://github.com/elastic/kibana/assets/23701614/a9065c86-eae4-43ce-bf4a-f1c9786076b5) As it turns out, this was due to inadvertently removing the `ListWithKuerySchema` from the schema definition for `GET /package_policies`, which escaped code review. This PR fixes that. ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../plugins/fleet/server/types/rest_spec/package_policy.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts b/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts index c64f4db8a70d4..1538f380fb7b4 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts @@ -15,13 +15,10 @@ import { import { inputsFormat } from '../../../common/constants'; -import { BulkRequestBodySchema } from './common'; +import { ListWithKuerySchema, BulkRequestBodySchema } from './common'; export const GetPackagePoliciesRequestSchema = { - query: schema.object({ - page: schema.number({ defaultValue: 1 }), - perPage: schema.number({ defaultValue: 20 }), - kuery: schema.maybe(schema.string()), + query: ListWithKuerySchema.extends({ format: schema.maybe( schema.oneOf([schema.literal(inputsFormat.Simplified), schema.literal(inputsFormat.Legacy)]) ), From 99aa6ab6ab7a20f1132456c8cface7f947ddecf1 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Thu, 13 Jul 2023 11:57:13 +0300 Subject: [PATCH 92/97] [Textbased] Refactor flyout state management (#161256) ## Summary This PR doesn't introduce a new feature to the users. It is mostly a refactoring for the edit flyout. This change will make it easier to make the flyout work with the formBased charts as it uses the exact same functions as the mounter (Lens editor) ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../layout/hooks/use_lens_suggestions.ts | 2 +- .../get_edit_lens_configuration.tsx | 12 ++- .../lens_configuration_flyout.test.tsx | 21 +----- .../lens_configuration_flyout.tsx | 74 ++++++------------- .../datasources/text_based/datapanel.tsx | 2 +- .../text_based/text_based_languages.tsx | 9 +-- .../public/datasources/text_based/types.ts | 2 +- .../config_panel/config_panel.tsx | 31 +++++++- .../lens/public/embeddable/embeddable.tsx | 31 ++++++-- .../lens/public/state_management/index.ts | 1 - .../init_middleware/load_initial.ts | 10 +-- .../state_management/lens_slice.test.ts | 23 ------ .../public/state_management/lens_slice.ts | 52 +------------ .../apps/discover/visualize_field.ts | 1 + 14 files changed, 108 insertions(+), 163 deletions(-) diff --git a/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts b/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts index a8a90faa18a9a..fffadcc9bc619 100644 --- a/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts +++ b/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts @@ -69,7 +69,7 @@ export const useLensSuggestions = ({ return { allSuggestions, currentSuggestion, - suggestionUnsupported: !dataView.isTimeBased(), + suggestionUnsupported: !currentSuggestion && !dataView.isTimeBased(), }; }; diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx index 65ad607a91da5..e95f83438294d 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx @@ -18,9 +18,10 @@ import { LensRootStore, LensAppState, LensState, + loadInitial, } from '../../../state_management'; import { getPreloadedState } from '../../../state_management/lens_slice'; - +import { generateId } from '../../../id_generator'; import type { DatasourceMap, VisualizationMap } from '../../../types'; import { LensEditConfigurationFlyout, @@ -55,6 +56,7 @@ export function getEditLensConfiguration( wrapInFlyout, datasourceId, adaptersTables, + panelId, }: EditLensConfigurationProps) => { const [lensServices, setLensServices] = useState(); useEffect(() => { @@ -89,6 +91,14 @@ export function getEditLensConfiguration( const lensStore: LensRootStore = makeConfigureStore(storeDeps, { lens: getPreloadedState(storeDeps) as LensAppState, } as unknown as PreloadedState); + lensStore.dispatch( + loadInitial({ + initialInput: { + attributes, + id: panelId ?? generateId(), + }, + }) + ); const getWrapper = (children: JSX.Element) => { if (wrapInFlyout) { diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx index f1a2ba0630993..24c8ced2a7e5f 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx @@ -148,12 +148,7 @@ describe('LensEditConfigurationFlyout', () => { "activeData": Object {}, "dataViews": Object { "indexPatternRefs": Array [], - "indexPatterns": Object { - "index1": Object { - "id": "index1", - "isPersisted": [Function], - }, - }, + "indexPatterns": Object {}, }, "datasourceLayers": Object { "a": Object { @@ -207,12 +202,7 @@ describe('LensEditConfigurationFlyout', () => { "activeData": Object {}, "dataViews": Object { "indexPatternRefs": Array [], - "indexPatterns": Object { - "index1": Object { - "id": "index1", - "isPersisted": [Function], - }, - }, + "indexPatterns": Object {}, }, "datasourceLayers": Object { "a": Object { @@ -257,12 +247,7 @@ describe('LensEditConfigurationFlyout', () => { "activeData": Object {}, "dataViews": Object { "indexPatternRefs": Array [], - "indexPatterns": Object { - "index1": Object { - "id": "index1", - "isPersisted": [Function], - }, - }, + "indexPatterns": Object {}, }, "datasourceLayers": Object { "a": Object { diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx index 98add346d114d..24b84f7665c5a 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -22,16 +22,11 @@ import { css } from '@emotion/react'; import type { CoreStart } from '@kbn/core/public'; import type { Datatable } from '@kbn/expressions-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; -import { getResolvedDateRange } from '../../../utils'; import type { LensPluginStartDependencies } from '../../../plugin'; -import { - DataViewsState, - useLensDispatch, - updateStateFromSuggestion, -} from '../../../state_management'; +import { useLensSelector, selectFramePublicAPI } from '../../../state_management'; import { VisualizationToolbar } from '../../../editor_frame_service/editor_frame/workspace_panel'; -import type { DatasourceMap, VisualizationMap, DatasourceLayers } from '../../../types'; +import type { DatasourceMap, VisualizationMap } from '../../../types'; import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; import { ConfigPanelWrapper } from '../../../editor_frame_service/editor_frame/config_panel/config_panel'; @@ -45,6 +40,7 @@ export interface EditConfigPanelProps { datasourceMap: DatasourceMap; closeFlyout?: () => void; wrapInFlyout?: boolean; + panelId?: string; datasourceId: 'formBased' | 'textBased'; adaptersTables?: Record; } @@ -61,57 +57,33 @@ export function LensEditConfigurationFlyout({ closeFlyout, adaptersTables, }: EditConfigPanelProps) { - const currentDataViewId = dataView.id ?? ''; const datasourceState = attributes.state.datasourceStates[datasourceId]; const activeVisualization = visualizationMap[attributes.visualizationType]; const activeDatasource = datasourceMap[datasourceId]; - const dispatchLens = useLensDispatch(); const { euiTheme } = useEuiTheme(); - const dataViews = useMemo(() => { - return { - indexPatterns: { - [currentDataViewId]: dataView, - }, - indexPatternRefs: [], - } as unknown as DataViewsState; - }, [currentDataViewId, dataView]); - dispatchLens( - updateStateFromSuggestion({ - newDatasourceId: datasourceId, - visualizationId: activeVisualization.id, - visualizationState: attributes.state.visualization, - datasourceState, - dataViews, - }) - ); - const datasourceLayers: DatasourceLayers = useMemo(() => { - return {}; - }, []); const activeData: Record = useMemo(() => { return {}; }, []); const layers = activeDatasource.getLayers(datasourceState); layers.forEach((layer) => { - datasourceLayers[layer] = datasourceMap[datasourceId].getPublicAPI({ - state: datasourceState, - layerId: layer, - indexPatterns: dataViews.indexPatterns, - }); if (adaptersTables) { activeData[layer] = Object.values(adaptersTables)[0]; } }); - const dateRange = getResolvedDateRange(startDependencies.data.query.timefilter.timefilter); - const framePublicAPI = useMemo(() => { - return { - activeData, - dataViews, - datasourceLayers, - dateRange, + const framePublicAPI = useLensSelector((state) => { + const newState = { + ...state, + lens: { + ...state.lens, + activeData, + }, }; - }, [activeData, dataViews, datasourceLayers, dateRange]); + return selectFramePublicAPI(newState, datasourceMap); + }); + const { isLoading } = useLensSelector((state) => state.lens); + if (isLoading) return null; const layerPanelsProps = { framePublicAPI, @@ -120,7 +92,7 @@ export function LensEditConfigurationFlyout({ core: coreStart, dataViews: startDependencies.dataViews, uiActions: startDependencies.uiActions, - hideLayerHeader: true, + hideLayerHeader: datasourceId === 'textBased', onUpdateStateCb: updateAll, }; return ( @@ -135,13 +107,15 @@ export function LensEditConfigurationFlyout({ > - + {datasourceId === 'textBased' && ( + + )} ({ dataViewId: null, - allFields: dataHasLoaded ? fieldList : null, + allFields: dataHasLoaded ? fieldList ?? [] : null, services: { dataViews, core, diff --git a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx index 831bb1501c8fc..a670846cc816d 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx @@ -225,7 +225,6 @@ export function getTextBasedDatasource({ const initState = state || { layers: {} }; return { ...initState, - fieldList: [], indexPatternRefs: refs, initialContext: context, }; @@ -407,7 +406,7 @@ export function getTextBasedDatasource({ (column) => column.columnId === props.columnId ); - const updatedFields = fields.map((f) => { + const updatedFields = fields?.map((f) => { return { ...f, compatible: props.isMetricDimension @@ -430,10 +429,10 @@ export function getTextBasedDatasource({ className="lnsIndexPatternDimensionEditor--padded" > { - const meta = fields.find((f) => f.name === choice.field)?.meta; + const meta = fields?.find((f) => f.name === choice.field)?.meta; const newColumn = { columnId: props.columnId, fieldName: choice.field, @@ -621,7 +620,7 @@ export function getTextBasedDatasource({ }; }, getDatasourceSuggestionsForField(state, draggedField) { - const field = state.fieldList.find((f) => f.id === (draggedField as TextBasedField).id); + const field = state.fieldList?.find((f) => f.id === (draggedField as TextBasedField).id); if (!field) return []; return Object.entries(state.layers)?.map(([id, layer]) => { const newId = generateId(); diff --git a/x-pack/plugins/lens/public/datasources/text_based/types.ts b/x-pack/plugins/lens/public/datasources/text_based/types.ts index 544996c904b77..8da183f9b9054 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/types.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/types.ts @@ -32,11 +32,11 @@ export interface TextBasedLayer { export interface TextBasedPersistedState { layers: Record; initialContext?: VisualizeFieldContext | VisualizeEditorContext; + fieldList?: DatatableColumn[]; } export type TextBasedPrivateState = TextBasedPersistedState & { indexPatternRefs: IndexPatternRef[]; - fieldList: DatatableColumn[]; }; export interface IndexPatternRef { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index 939cc191e3428..25568abab83c0 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -89,14 +89,18 @@ export function LayerPanels( if (datasourceId) { dispatchLens( updateDatasourceState({ - updater: (prevState: unknown) => - typeof newState === 'function' ? newState(prevState) : newState, + updater: (prevState: unknown) => { + onUpdateStateCb?.( + typeof newState === 'function' ? newState(prevState) : newState, + visualization.state + ); + return typeof newState === 'function' ? newState(prevState) : newState; + }, datasourceId, clearStagedPreview: false, dontSyncLinkedDimensions, }) ); - onUpdateStateCb?.(newState, visualization.state); } }, [dispatchLens, onUpdateStateCb, visualization.state] @@ -136,6 +140,7 @@ export function LayerPanels( typeof newVisualizationState === 'function' ? newVisualizationState(prevState.visualization.state) : newVisualizationState; + onUpdateStateCb?.(updatedDatasourceState, updatedVisualizationState); return { ...prevState, @@ -154,7 +159,6 @@ export function LayerPanels( }, }) ); - onUpdateStateCb?.(newDatasourceState, newVisualizationState); }, 0); }, [dispatchLens, onUpdateStateCb] @@ -195,14 +199,24 @@ export function LayerPanels( layerIds, }) ); + if (activeDatasourceId && onUpdateStateCb) { + const newState = lensStore.getState().lens; + onUpdateStateCb( + newState.datasourceStates[activeDatasourceId].state, + newState.visualization.state + ); + } removeLayerRef(layerToRemoveId); }, [ + activeDatasourceId, activeVisualization.id, datasourceMap, datasourceStates, dispatchLens, layerIds, + lensStore, + onUpdateStateCb, props.framePublicAPI.datasourceLayers, props.uiActions, removeLayerRef, @@ -242,7 +256,16 @@ export function LayerPanels( const addLayer: AddLayerFunction = (layerType, extraArg, ignoreInitialValues) => { const layerId = generateId(); + dispatchLens(addLayerAction({ layerId, layerType, extraArg, ignoreInitialValues })); + + if (activeDatasourceId && onUpdateStateCb) { + const newState = lensStore.getState().lens; + onUpdateStateCb( + newState.datasourceStates[activeDatasourceId].state, + newState.visualization.state + ); + } setNextFocusedLayerId(layerId); }; diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index c690f875debf5..516617c2dc852 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -120,6 +120,7 @@ import { getIndexPatternsObjects, getSearchWarningMessages, inferTimeField, + extractReferencesFromState, } from '../utils'; import { getLayerMetaInfo, combineQueryAndFilters } from '../app_plugin/show_underlying_data'; import { @@ -741,19 +742,37 @@ export class Embeddable async updateVisualization(datasourceState: unknown, visualizationState: unknown) { const viz = this.savedVis; - const datasourceId = (this.activeDatasourceId ?? + const activeDatasourceId = (this.activeDatasourceId ?? 'formBased') as EditLensConfigurationProps['datasourceId']; if (viz?.state) { + const datasourceStates = { + ...viz.state.datasourceStates, + [activeDatasourceId]: datasourceState, + }; + const references = extractReferencesFromState({ + activeDatasources: Object.keys(datasourceStates).reduce( + (acc, datasourceId) => ({ + ...acc, + [datasourceId]: this.deps.datasourceMap[datasourceId], + }), + {} + ), + datasourceStates: Object.fromEntries( + Object.entries(datasourceStates).map(([id, state]) => [id, { isLoading: false, state }]) + ), + visualizationState, + activeVisualization: this.activeVisualizationId + ? this.deps.visualizationMap[this.activeVisualizationId] + : undefined, + }); const attrs = { ...viz, state: { ...viz.state, visualization: visualizationState, - datasourceStates: { - ...viz.state.datasourceStates, - [datasourceId]: datasourceState, - }, + datasourceStates, }, + references, }; this.updateInput({ attributes: attrs }); } @@ -770,6 +789,7 @@ export class Embeddable const datasourceId = (this.activeDatasourceId ?? 'formBased') as EditLensConfigurationProps['datasourceId']; + const attributes = this.savedVis as TypedLensByValueInput['attributes']; const dataView = this.dataViews[0]; if (attributes) { @@ -780,6 +800,7 @@ export class Embeddable updateAll={this.updateVisualization.bind(this)} datasourceId={datasourceId} adaptersTables={this.lensInspector.adapters.tables?.tables} + panelId={this.id} /> ); } diff --git a/x-pack/plugins/lens/public/state_management/index.ts b/x-pack/plugins/lens/public/state_management/index.ts index f4b333e25c815..9a9a4005714aa 100644 --- a/x-pack/plugins/lens/public/state_management/index.ts +++ b/x-pack/plugins/lens/public/state_management/index.ts @@ -35,7 +35,6 @@ export const { submitSuggestion, switchDatasource, switchAndCleanDatasource, - updateStateFromSuggestion, updateIndexPatterns, setToggleFullscreen, initEmpty, diff --git a/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts b/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts index 45b05ebbb157a..59e022345c603 100644 --- a/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts +++ b/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts @@ -92,7 +92,7 @@ export function loadInitial( initialInput, history, }: { - redirectCallback: (savedObjectId?: string) => void; + redirectCallback?: (savedObjectId?: string) => void; initialInput?: LensEmbeddableInput; history?: History; }, @@ -269,7 +269,7 @@ export function loadInitial( notifications.toasts.addDanger({ title: e.message, }); - redirectCallback(); + redirectCallback?.(); }); } @@ -376,7 +376,7 @@ export function loadInitial( }) ); } else { - redirectCallback(); + redirectCallback?.(); } }, () => { @@ -385,13 +385,13 @@ export function loadInitial( isLoading: false, }) ); - redirectCallback(); + redirectCallback?.(); } ) .catch((e: { message: string }) => { notifications.toasts.addDanger({ title: e.message, }); - redirectCallback(); + redirectCallback?.(); }); } diff --git a/x-pack/plugins/lens/public/state_management/lens_slice.test.ts b/x-pack/plugins/lens/public/state_management/lens_slice.test.ts index 0371d5564d503..c69931837b3aa 100644 --- a/x-pack/plugins/lens/public/state_management/lens_slice.test.ts +++ b/x-pack/plugins/lens/public/state_management/lens_slice.test.ts @@ -10,7 +10,6 @@ import type { Query } from '@kbn/es-query'; import { switchDatasource, switchAndCleanDatasource, - updateStateFromSuggestion, switchVisualization, setState, updateState, @@ -272,28 +271,6 @@ describe('lensSlice', () => { }); }); - describe('update the state from the suggestion', () => { - it('should switch active datasource and initialize new state', () => { - store.dispatch( - updateStateFromSuggestion({ - newDatasourceId: 'testDatasource2', - visualizationId: 'testVis', - visualizationState: ['col1', 'col2'], - datasourceState: {}, - dataViews: { indexPatterns: {} } as DataViewsState, - }) - ); - expect(store.getState().lens.activeDatasourceId).toEqual('testDatasource2'); - expect(store.getState().lens.datasourceStates.testDatasource2.isLoading).toEqual(false); - expect(store.getState().lens.datasourceStates.testDatasource2.state).toStrictEqual({}); - expect(store.getState().lens.visualization).toStrictEqual({ - activeId: 'testVis', - state: ['col1', 'col2'], - }); - expect(store.getState().lens.dataViews).toEqual({ indexPatterns: {} }); - }); - }); - describe('adding or removing layer', () => { const testDatasource = (datasourceId: string) => { return { diff --git a/x-pack/plugins/lens/public/state_management/lens_slice.ts b/x-pack/plugins/lens/public/state_management/lens_slice.ts index 60d15f532d3d4..401bff694546a 100644 --- a/x-pack/plugins/lens/public/state_management/lens_slice.ts +++ b/x-pack/plugins/lens/public/state_management/lens_slice.ts @@ -187,18 +187,11 @@ export const switchAndCleanDatasource = createAction<{ visualizationId: string | null; currentIndexPatternId?: string; }>('lens/switchAndCleanDatasource'); -export const updateStateFromSuggestion = createAction<{ - newDatasourceId: string; - visualizationId: string | null; - visualizationState: unknown; - datasourceState: unknown; - dataViews: DataViewsState; -}>('lens/updateStateFromSuggestion'); export const navigateAway = createAction('lens/navigateAway'); export const loadInitial = createAction<{ initialInput?: LensEmbeddableInput; - redirectCallback: (savedObjectId?: string) => void; - history: History; + redirectCallback?: (savedObjectId?: string) => void; + history?: History; }>('lens/loadInitial'); export const initEmpty = createAction( 'initEmpty', @@ -288,7 +281,6 @@ export const lensActions = { submitSuggestion, switchDatasource, switchAndCleanDatasource, - updateStateFromSuggestion, navigateAway, loadInitial, initEmpty, @@ -870,49 +862,13 @@ export const makeLensReducer = (storeDeps: LensStoreDeps) => { }, }; }, - [updateStateFromSuggestion.type]: ( - state, - { - payload, - }: { - payload: { - newDatasourceId: string; - visualizationId: string; - visualizationState: unknown; - datasourceState: unknown; - dataViews: DataViewsState; - }; - } - ) => { - const visualization = { - activeId: payload.visualizationId, - state: payload.visualizationState, - }; - - const datasourceState = payload.datasourceState; - - return { - ...state, - datasourceStates: { - [payload.newDatasourceId]: { - state: datasourceState, - isLoading: false, - }, - }, - activeDatasourceId: payload.newDatasourceId, - visualization: { - ...visualization, - }, - dataViews: payload.dataViews, - }; - }, [navigateAway.type]: (state) => state, [loadInitial.type]: ( state, payload: PayloadAction<{ initialInput?: LensEmbeddableInput; - redirectCallback: (savedObjectId?: string) => void; - history: History; + redirectCallback?: (savedObjectId?: string) => void; + history?: History; }> ) => state, [initEmpty.type]: ( diff --git a/x-pack/test/functional/apps/discover/visualize_field.ts b/x-pack/test/functional/apps/discover/visualize_field.ts index 236ceaffa1b5d..32cd9b5360da0 100644 --- a/x-pack/test/functional/apps/discover/visualize_field.ts +++ b/x-pack/test/functional/apps/discover/visualize_field.ts @@ -171,6 +171,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await PageObjects.discover.chooseLensChart('Bar vertical stacked'); await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.click('TextBasedLangEditor-expand'); await testSubjects.click('unifiedHistogramEditFlyoutVisualization'); expect(await testSubjects.exists('xyVisChart')).to.be(true); expect(await PageObjects.lens.canRemoveDimension('lnsXY_xDimensionPanel')).to.equal(true); From 52c645f88633865ab4a20e9dcfed56f8e059ea34 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 13 Jul 2023 09:59:44 +0100 Subject: [PATCH 93/97] [Logs+] Add title / icons to installed packages API (#161777) ## Summary Implements https://github.com/elastic/kibana/issues/160935. This PR adds the `title` and `icons` (also `description` since it was there) properties to the installed packages API, these are extracted from the matching manifest assets (so that we don't have to call the registry, and can query for multiple items at once). Discover has also been updated to use these new properties. List: Screenshot 2023-07-12 at 17 13 52 With selection: Screenshot 2023-07-12 at 17 14 10 I've made this robust against a matching manifest asset not being found - I don't think this is actually possible, but just incase. ## Testing - When accessing the log explorer profile within Discover pretty titles should be displayed in the dataset selector - When accessing the log explorer profile within Discover icons should be displayed in the dataset selector --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../common/datasets/models/dataset.ts | 8 +- .../common/datasets/models/integration.ts | 6 + .../common/datasets/types.ts | 29 +++- .../sub_components/datasets_popover.tsx | 1 + .../components/dataset_selector/utils.tsx | 8 +- .../fleet/common/types/rest_spec/epm.ts | 2 +- .../server/services/epm/packages/get.test.ts | 142 +++++++++++++----- .../fleet/server/services/epm/packages/get.ts | 61 +++++++- 8 files changed, 204 insertions(+), 53 deletions(-) diff --git a/x-pack/plugins/discover_log_explorer/common/datasets/models/dataset.ts b/x-pack/plugins/discover_log_explorer/common/datasets/models/dataset.ts index 38a6024de277c..9db74da31543f 100644 --- a/x-pack/plugins/discover_log_explorer/common/datasets/models/dataset.ts +++ b/x-pack/plugins/discover_log_explorer/common/datasets/models/dataset.ts @@ -10,7 +10,7 @@ import { DataViewSpec } from '@kbn/data-views-plugin/common'; import { IndexPattern } from '@kbn/io-ts-utils'; import { DatasetId, DatasetType, IntegrationType } from '../types'; -type IntegrationBase = Pick; +type IntegrationBase = Pick; interface DatasetDeps extends DatasetType { iconType?: IconType; } @@ -29,13 +29,15 @@ export class Dataset { this.title = dataset.title ?? dataset.name; this.parentIntegration = parentIntegration && { name: parentIntegration.name, + title: parentIntegration.title, + icons: parentIntegration.icons, version: parentIntegration.version, }; } getFullTitle(): string { - return this.parentIntegration?.name - ? `[${this.parentIntegration.name}] ${this.title}` + return this.parentIntegration?.title + ? `[${this.parentIntegration.title}] ${this.title}` : this.title; } diff --git a/x-pack/plugins/discover_log_explorer/common/datasets/models/integration.ts b/x-pack/plugins/discover_log_explorer/common/datasets/models/integration.ts index 764eeeb40b9a0..95411309d2cd2 100644 --- a/x-pack/plugins/discover_log_explorer/common/datasets/models/integration.ts +++ b/x-pack/plugins/discover_log_explorer/common/datasets/models/integration.ts @@ -11,6 +11,9 @@ import { IntegrationId, IntegrationType } from '../types'; export class Integration { id: IntegrationId; name: IntegrationType['name']; + title?: IntegrationType['title']; + description?: IntegrationType['description']; + icons?: IntegrationType['icons']; status: IntegrationType['status']; version: IntegrationType['version']; datasets: Dataset[]; @@ -18,6 +21,9 @@ export class Integration { private constructor(integration: Integration) { this.id = integration.id; this.name = integration.name; + this.title = integration.title ?? integration.name; + this.description = integration.description; + this.icons = integration.icons; this.status = integration.status; this.version = integration.version; this.datasets = integration.datasets; diff --git a/x-pack/plugins/discover_log_explorer/common/datasets/types.ts b/x-pack/plugins/discover_log_explorer/common/datasets/types.ts index a770aee308423..b15916a1162b1 100644 --- a/x-pack/plugins/discover_log_explorer/common/datasets/types.ts +++ b/x-pack/plugins/discover_log_explorer/common/datasets/types.ts @@ -25,12 +25,29 @@ const integrationStatusRT = rt.keyof({ install_failed: null, }); -export const integrationRT = rt.type({ - name: rt.string, - status: integrationStatusRT, - version: rt.string, - dataStreams: rt.array(datasetRT), -}); +export const integrationRT = rt.intersection([ + rt.type({ + name: rt.string, + status: integrationStatusRT, + version: rt.string, + dataStreams: rt.array(datasetRT), + }), + rt.partial({ + title: rt.union([rt.string, rt.undefined]), + icons: rt.union([ + rt.array( + rt.type({ + src: rt.string, + title: rt.string, + size: rt.string, + type: rt.string, + }) + ), + rt.undefined, + ]), + description: rt.union([rt.string, rt.undefined]), + }), +]); export type DatasetId = `dataset-${string}`; export type IntegrationId = `integration-${string}-${string}`; diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/datasets_popover.tsx b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/datasets_popover.tsx index 0ed65b4e50d8b..77e142d81b999 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/datasets_popover.tsx +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/sub_components/datasets_popover.tsx @@ -60,6 +60,7 @@ export const DatasetsPopover = ({ diff --git a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/utils.tsx b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/utils.tsx index b135c0c22202b..b3e5822dfbbbd 100644 --- a/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/utils.tsx +++ b/x-pack/plugins/discover_log_explorer/public/components/dataset_selector/utils.tsx @@ -55,19 +55,19 @@ export const buildIntegrationsTree = ({ }: IntegrationsTreeParams) => { return integrations.reduce( (integrationsTree: IntegrationsTree, integration, pos) => { - const { name, version, datasets } = integration; + const { name, title, version, datasets, icons } = integration; const isLastIntegration = pos === integrations.length - 1; integrationsTree.items.push({ - name, - icon: , + name: title, + icon: , panel: integration.id, ...(isLastIntegration && { buttonRef: spyRef }), }); integrationsTree.panels.push({ id: integration.id, - title: name, + title, width: DATA_VIEW_POPOVER_CONTENT_WIDTH, items: datasets.map((dataset) => ({ name: dataset.title, diff --git a/x-pack/plugins/fleet/common/types/rest_spec/epm.ts b/x-pack/plugins/fleet/common/types/rest_spec/epm.ts index 5658dea03c826..fcec6fc0f8fa5 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/epm.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/epm.ts @@ -51,7 +51,7 @@ export interface GetPackagesResponse { response?: PackageList; } -interface InstalledPackage { +export interface InstalledPackage { name: string; version: string; status: EpmPackageInstallStatus; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts index 836be792db068..445bc6fca6719 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts @@ -10,7 +10,11 @@ import type { SavedObjectsClientContract, SavedObjectsFindResult } from '@kbn/co import { SavedObjectsErrorHelpers } from '@kbn/core/server'; import { savedObjectsClientMock } from '@kbn/core/server/mocks'; -import { PACKAGES_SAVED_OBJECT_TYPE, PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../../../../common'; +import { + ASSETS_SAVED_OBJECT_TYPE, + PACKAGES_SAVED_OBJECT_TYPE, + PACKAGE_POLICY_SAVED_OBJECT_TYPE, +} from '../../../../common'; import type { RegistryPackage } from '../../../../common/types'; import type { PackagePolicySOAttributes } from '../../../types'; @@ -435,24 +439,51 @@ owner: elastic`, it('Passes the correct parameters to the SavedObjects client', async () => { const soClient = savedObjectsClientMock.create(); - soClient.find.mockResolvedValue({ - saved_objects: [ - { - type: 'epm-packages', - id: 'elastic_agent', - attributes: { - es_index_patterns: { - apm_server_logs: 'logs-elastic_agent.apm_server-*', - apm_server_metrics: 'metrics-elastic_agent.apm_server-*', + soClient.find.mockImplementation(async (options) => { + if (options.type === PACKAGES_SAVED_OBJECT_TYPE) { + return { + total: 5, + saved_objects: [ + { + type: 'epm-packages', + id: 'elastic_agent', + attributes: { + es_index_patterns: { + apm_server_logs: 'logs-elastic_agent.apm_server-*', + apm_server_metrics: 'metrics-elastic_agent.apm_server-*', + }, + name: 'elastic_agent', + version: '1.7.0', + install_status: 'installed', + }, + references: [], + sort: ['elastic_agent'], }, - name: 'elastic_agent', - version: '1.7.0', - install_status: 'installed', - }, - references: [], - }, - ], - } as any); + ], + } as any; + } else if (options.type === ASSETS_SAVED_OBJECT_TYPE) { + return { + total: 5, + saved_objects: [ + { + type: 'epm-packages-assets', + id: '338b6f9e-e126-5f1e-abb9-afe017d4788b', + attributes: { + package_name: 'elastic_agent', + package_version: '1.8.0', + install_source: 'upload', + asset_path: 'elastic_agent-1.8.0/manifest.yml', + media_type: 'text/yaml; charset=utf-8', + data_utf8: + 'name: elastic_agent\ntitle: Elastic Agent\nversion: 1.8.0\ndescription: Collect logs and metrics from Elastic Agents.\ntype: integration\nformat_version: 1.0.0\nlicense: basic\ncategories: ["elastic_stack"]\nconditions:\n kibana.version: "^8.7.1"\nowner:\n github: elastic/elastic-agent\nicons:\n - src: /img/logo_elastic_agent.svg\n title: logo Elastic Agent\n size: 64x64\n type: image/svg+xml\nscreenshots:\n - src: /img/elastic_agent_overview.png\n title: Elastic Agent Overview\n size: 2560×1234\n type: image/png\n - src: /img/elastic_agent_metrics.png\n title: Elastic Agent Metrics\n size: 2560×1234\n type: image/png\n - src: /img/elastic_agent_info.png\n title: Elastic Agent Information\n size: 2560×1234\n type: image/png\n - src: /img/elastic_agent_integrations.png\n title: Elastic Agent Integrations\n size: 2560×1234\n type: image/png\n', + data_base64: '', + }, + references: [], + }, + ], + } as any; + } + }); await getInstalledPackages({ savedObjectsClient: soClient, @@ -550,26 +581,51 @@ owner: elastic`, it('Formats items correctly', async () => { const soClient = savedObjectsClientMock.create(); - soClient.find.mockResolvedValue({ - total: 5, - saved_objects: [ - { - type: 'epm-packages', - id: 'elastic_agent', - attributes: { - es_index_patterns: { - apm_server_logs: 'logs-elastic_agent.apm_server-*', - apm_server_metrics: 'metrics-elastic_agent.apm_server-*', + soClient.find.mockImplementation(async (options) => { + if (options.type === PACKAGES_SAVED_OBJECT_TYPE) { + return { + total: 5, + saved_objects: [ + { + type: 'epm-packages', + id: 'elastic_agent', + attributes: { + es_index_patterns: { + apm_server_logs: 'logs-elastic_agent.apm_server-*', + apm_server_metrics: 'metrics-elastic_agent.apm_server-*', + }, + name: 'elastic_agent', + version: '1.8.0', + install_status: 'installed', + }, + references: [], + sort: ['elastic_agent'], }, - name: 'elastic_agent', - version: '1.7.0', - install_status: 'installed', - }, - references: [], - sort: ['elastic_agent'], - }, - ], - } as any); + ], + } as any; + } else if (options.type === ASSETS_SAVED_OBJECT_TYPE) { + return { + total: 5, + saved_objects: [ + { + type: 'epm-packages-assets', + id: '338b6f9e-e126-5f1e-abb9-afe017d4788b', + attributes: { + package_name: 'elastic_agent', + package_version: '1.8.0', + install_source: 'upload', + asset_path: 'elastic_agent-1.8.0/manifest.yml', + media_type: 'text/yaml; charset=utf-8', + data_utf8: + 'name: elastic_agent\ntitle: Elastic Agent\nversion: 1.8.0\ndescription: Collect logs and metrics from Elastic Agents.\ntype: integration\nformat_version: 1.0.0\nlicense: basic\ncategories: ["elastic_stack"]\nconditions:\n kibana.version: "^8.7.1"\nowner:\n github: elastic/elastic-agent\nicons:\n - src: /img/logo_elastic_agent.svg\n title: logo Elastic Agent\n size: 64x64\n type: image/svg+xml\nscreenshots:\n - src: /img/elastic_agent_overview.png\n title: Elastic Agent Overview\n size: 2560×1234\n type: image/png\n - src: /img/elastic_agent_metrics.png\n title: Elastic Agent Metrics\n size: 2560×1234\n type: image/png\n - src: /img/elastic_agent_info.png\n title: Elastic Agent Information\n size: 2560×1234\n type: image/png\n - src: /img/elastic_agent_integrations.png\n title: Elastic Agent Integrations\n size: 2560×1234\n type: image/png\n', + data_base64: '', + }, + references: [], + }, + ], + } as any; + } + }); const results = await getInstalledPackages({ savedObjectsClient: soClient, @@ -586,7 +642,17 @@ owner: elastic`, dataStreams: [{ name: 'logs-elastic_agent.apm_server-*', title: 'apm_server_logs' }], name: 'elastic_agent', status: 'installed', - version: '1.7.0', + version: '1.8.0', + title: 'Elastic Agent', + description: 'Collect logs and metrics from Elastic Agents.', + icons: [ + { + size: '64x64', + src: '/img/logo_elastic_agent.svg', + title: 'logo Elastic Agent', + type: 'image/svg+xml', + }, + ], }, ], searchAfter: ['elastic_agent'], diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index 19bedd8ff842e..96113407222f6 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -4,6 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + +import * as yaml from 'js-yaml'; import pMap from 'p-map'; import type { SavedObjectsClientContract, SavedObjectsFindOptions } from '@kbn/core/server'; import semverGte from 'semver/functions/gte'; @@ -18,6 +20,7 @@ import { buildNode as buildFunctionNode } from '@kbn/es-query/src/kuery/node_typ import { buildNode as buildWildcardNode } from '@kbn/es-query/src/kuery/node_types/wildcard'; import { + ASSETS_SAVED_OBJECT_TYPE, installationStatuses, PACKAGE_POLICY_SAVED_OBJECT_TYPE, SO_SEARCH_LIMIT, @@ -28,6 +31,8 @@ import type { Installable, PackageDataStreamTypes, PackageList, + InstalledPackage, + PackageSpecManifest, } from '../../../../common/types'; import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../constants'; import type { @@ -45,6 +50,7 @@ import { } from '../../../errors'; import { appContextService } from '../..'; import * as Registry from '../registry'; +import type { PackageAsset } from '../archive/storage'; import { getEsPackage } from '../archive/storage'; import { getArchivePackage } from '../archive'; import { normalizeKuery } from '../../saved_object'; @@ -189,8 +195,25 @@ export async function getInstalledPackages(options: GetInstalledPackagesOptions) }; }); + const integrationManifests = + integrations.length > 0 + ? await getInstalledPackageManifests(savedObjectsClient, integrations) + : new Map(); + + const integrationsWithManifestContent = integrations.map((integration) => { + const { name, version } = integration; + const integrationAsset = integrationManifests.get(`${name}-${version}/manifest.yml`); + + return { + ...integration, + title: integrationAsset?.title ?? undefined, + description: integrationAsset?.description ?? undefined, + icons: integrationAsset?.icons ?? undefined, + }; + }); + return { - items: integrations, + items: integrationsWithManifestContent, total: packageSavedObjects.total, searchAfter: packageSavedObjects.saved_objects.at(-1)?.sort, // Enable ability to use searchAfter in subsequent queries }; @@ -306,6 +329,42 @@ export async function getInstalledPackageSavedObjects( return result; } +export async function getInstalledPackageManifests( + savedObjectsClient: SavedObjectsClientContract, + installedPackages: InstalledPackage[] +) { + const pathFilters = installedPackages.map((installedPackage) => { + const { name, version } = installedPackage; + return nodeBuilder.is( + `${ASSETS_SAVED_OBJECT_TYPE}.attributes.asset_path`, + `${name}-${version}/manifest.yml` + ); + }); + + const result = await savedObjectsClient.find({ + type: ASSETS_SAVED_OBJECT_TYPE, + filter: nodeBuilder.or(pathFilters), + }); + + const parsedManifests = result.saved_objects.reduce>( + (acc, asset) => { + acc.set(asset.attributes.asset_path, yaml.load(asset.attributes.data_utf8)); + return acc; + }, + new Map() + ); + + for (const savedObject of result.saved_objects) { + auditLoggingService.writeCustomSoAuditLog({ + action: 'find', + id: savedObject.id, + savedObjectType: ASSETS_SAVED_OBJECT_TYPE, + }); + } + + return parsedManifests; +} + function getInstalledPackageSavedObjectDataStreams( indexPatterns: Record, dataStreamType?: string From 5b896758359f8efce35602c06a0ccfd3748fe39f Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Thu, 13 Jul 2023 10:00:58 +0100 Subject: [PATCH 94/97] [Logs+] API to create a basic integration (#160777) ## Summary Closes https://github.com/elastic/kibana/issues/159991 Fields that have been utilised to fulfil `basic` and `agent` fields can be easily amended if these are incorrect. Multiple datasets are supported, and these can contain more than one type. ## Testing A curl command similar to the following should allow you to hit the API (check the credentials etc): ``` curl -XPOST -u 'elastic:changeme' -H 'kbn-xsrf: something' -d '{ "integrationName": "web_custom_nginx", "datasets": [{"name": "access", "type": "logs"}, {"name": "error", "type": "metrics"}, {"name": "warning", "type":"logs"}] }' 'http://localhost:5601//api/fleet/epm/custom_integrations' ``` ## History / context - [Prototype learnings](https://github.com/elastic/kibana/issues/158552#issuecomment-1598685163) - [Prototype PR](https://github.com/elastic/kibana/pull/160003) ## Results / expectations API response (with installed assets): ![Screenshot 2023-07-05 at 16 56 33](https://github.com/elastic/kibana/assets/471693/fc4a0bab-7057-430a-8c03-18dd4ee17ab7) We see the custom integration in "installed integrations" (albeit with a verification warning): ![Screenshot 2023-07-05 at 16 57 14](https://github.com/elastic/kibana/assets/471693/0c9177d2-2871-490f-9b5c-f338e96484c4) We see the custom integration in Discover with the logs explorer profile: ![Screenshot 2023-07-05 at 16 58 20](https://github.com/elastic/kibana/assets/471693/30c556f2-9fcd-416e-8047-5976fc11ffa2) The assets are installed correctly: ![Screenshot 2023-07-05 at 16 59 06](https://github.com/elastic/kibana/assets/471693/abb82632-f619-4fc3-be93-dc6ce97abedd) ![Screenshot 2023-07-05 at 16 59 20](https://github.com/elastic/kibana/assets/471693/ca1c1da5-1e4b-422c-9edb-0f56e0ed3f98) ![Screenshot 2023-07-05 at 16 59 36](https://github.com/elastic/kibana/assets/471693/8bd60d7e-aebc-4833-b423-eba3336fb42c) --- x-pack/plugins/fleet/common/constants/epm.ts | 3 + .../plugins/fleet/common/constants/routes.ts | 1 + .../plugins/fleet/common/types/models/epm.ts | 2 +- .../fleet/server/routes/epm/handlers.ts | 40 +++ .../plugins/fleet/server/routes/epm/index.ts | 13 + .../custom_integrations/assets/cache.ts | 24 ++ .../assets/dataset/fields.ts | 292 ++++++++++++++++++ .../assets/dataset/index.ts | 10 + .../assets/dataset/ingest_pipeline.ts | 29 ++ .../assets/dataset/manifest.ts | 21 ++ .../assets/dataset/utils.ts | 27 ++ .../custom_integrations/assets/generate.ts | 63 ++++ .../custom_integrations/assets/index.ts | 10 + .../custom_integrations/assets/manifest.ts | 38 +++ .../packages/custom_integrations/constants.ts | 8 + .../epm/packages/custom_integrations/index.ts | 10 + .../epm/packages/custom_integrations/utils.ts | 18 ++ .../server/services/epm/packages/install.ts | 93 +++++- .../fleet/server/types/rest_spec/epm.ts | 19 ++ .../fleet_api_integration/apis/epm/index.js | 1 + .../apis/epm/install_custom.ts | 102 ++++++ 21 files changed, 821 insertions(+), 3 deletions(-) create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/cache.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/fields.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/index.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/ingest_pipeline.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/manifest.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/utils.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/generate.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/index.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/manifest.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/constants.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/index.ts create mode 100644 x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/utils.ts create mode 100644 x-pack/test/fleet_api_integration/apis/epm/install_custom.ts diff --git a/x-pack/plugins/fleet/common/constants/epm.ts b/x-pack/plugins/fleet/common/constants/epm.ts index 4a0a055b5840f..52cb24271afa5 100644 --- a/x-pack/plugins/fleet/common/constants/epm.ts +++ b/x-pack/plugins/fleet/common/constants/epm.ts @@ -30,6 +30,9 @@ export const PACKAGE_TEMPLATE_SUFFIX = '@package'; export const USER_SETTINGS_TEMPLATE_SUFFIX = '@custom'; export const DATASET_VAR_NAME = 'data_stream.dataset'; + +export const CUSTOM_INTEGRATION_PACKAGE_SPEC_VERSION = '2.9.0'; + /* Package rules: | | autoUpdatePackages | diff --git a/x-pack/plugins/fleet/common/constants/routes.ts b/x-pack/plugins/fleet/common/constants/routes.ts index c14630284d2df..e40b9f8606fdb 100644 --- a/x-pack/plugins/fleet/common/constants/routes.ts +++ b/x-pack/plugins/fleet/common/constants/routes.ts @@ -34,6 +34,7 @@ export const EPM_API_ROUTES = { DATA_STREAMS_PATTERN: `${EPM_API_ROOT}/data_streams`, INSTALL_FROM_REGISTRY_PATTERN: EPM_PACKAGES_ONE, INSTALL_BY_UPLOAD_PATTERN: EPM_PACKAGES_MANY, + CUSTOM_INTEGRATIONS_PATTERN: `${EPM_API_ROOT}/custom_integrations`, DELETE_PATTERN: EPM_PACKAGES_ONE, FILEPATH_PATTERN: `${EPM_PACKAGES_ONE}/{filePath*}`, CATEGORIES_PATTERN: `${EPM_API_ROOT}/categories`, diff --git a/x-pack/plugins/fleet/common/types/models/epm.ts b/x-pack/plugins/fleet/common/types/models/epm.ts index dcff8ae3071e7..a5cef67810713 100644 --- a/x-pack/plugins/fleet/common/types/models/epm.ts +++ b/x-pack/plugins/fleet/common/types/models/epm.ts @@ -34,7 +34,7 @@ export interface DefaultPackagesInstallationError { } export type InstallType = 'reinstall' | 'reupdate' | 'rollback' | 'update' | 'install' | 'unknown'; -export type InstallSource = 'registry' | 'upload' | 'bundled'; +export type InstallSource = 'registry' | 'upload' | 'bundled' | 'custom'; export type EpmPackageInstallStatus = 'installed' | 'installing' | 'install_failed'; diff --git a/x-pack/plugins/fleet/server/routes/epm/handlers.ts b/x-pack/plugins/fleet/server/routes/epm/handlers.ts index b3add5d5e1408..a0b6999f0feb6 100644 --- a/x-pack/plugins/fleet/server/routes/epm/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/epm/handlers.ts @@ -52,6 +52,7 @@ import type { UpdatePackageRequestSchema, GetLimitedPackagesRequestSchema, GetBulkAssetsRequestSchema, + CreateCustomIntegrationRequestSchema, } from '../../types'; import { bulkInstallPackages, @@ -403,6 +404,45 @@ export const installPackageFromRegistryHandler: FleetRequestHandler< return await defaultFleetErrorHandler({ error: res.error, response }); } }; +export const createCustomIntegrationHandler: FleetRequestHandler< + undefined, + undefined, + TypeOf +> = async (context, request, response) => { + const coreContext = await context.core; + const fleetContext = await context.fleet; + const savedObjectsClient = fleetContext.internalSoClient; + const esClient = coreContext.elasticsearch.client.asInternalUser; + const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined; + const kibanaVersion = appContextService.getKibanaVersion(); + const authorizationHeader = HTTPAuthorizationHeader.parseFromRequest(request, user?.username); + const spaceId = fleetContext.spaceId; + const { integrationName, force, datasets } = request.body; + + const res = await installPackage({ + installSource: 'custom', + savedObjectsClient, + pkgName: integrationName, + datasets, + esClient, + spaceId, + force, + authorizationHeader, + kibanaVersion, + }); + + if (!res.error) { + const body: InstallPackageResponse = { + items: res.assets || [], + _meta: { + install_source: res.installSource, + }, + }; + return response.ok({ body }); + } else { + return await defaultFleetErrorHandler({ error: res.error, response }); + } +}; const bulkInstallServiceResponseToHttpEntry = ( result: BulkInstallResponse diff --git a/x-pack/plugins/fleet/server/routes/epm/index.ts b/x-pack/plugins/fleet/server/routes/epm/index.ts index a2794f30b8bb2..8567e1b5686f7 100644 --- a/x-pack/plugins/fleet/server/routes/epm/index.ts +++ b/x-pack/plugins/fleet/server/routes/epm/index.ts @@ -43,6 +43,7 @@ import { UpdatePackageRequestSchemaDeprecated, ReauthorizeTransformRequestSchema, GetDataStreamsRequestSchema, + CreateCustomIntegrationRequestSchema, } from '../../types'; import { @@ -62,6 +63,7 @@ import { getVerificationKeyIdHandler, reauthorizeTransformsHandler, getDataStreamsHandler, + createCustomIntegrationHandler, } from './handlers'; const MAX_FILE_SIZE_BYTES = 104857600; // 100MB @@ -196,6 +198,17 @@ export const registerRoutes = (router: FleetAuthzRouter) => { installPackageByUploadHandler ); + router.post( + { + path: EPM_API_ROUTES.CUSTOM_INTEGRATIONS_PATTERN, + validate: CreateCustomIntegrationRequestSchema, + fleetAuthz: { + integrations: { installPackages: true }, + }, + }, + createCustomIntegrationHandler + ); + router.delete( { path: EPM_API_ROUTES.DELETE_PATTERN, diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/cache.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/cache.ts new file mode 100644 index 0000000000000..e44f6e2b522d7 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/cache.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { setArchiveEntry, setArchiveFilelist } from '../../../archive'; + +interface Assets { + path: string; + content: Buffer; +} +export const cacheAssets = (assets: Assets[], name: string, version: string) => { + const paths = assets.map((asset) => asset.path); + + setArchiveFilelist({ name, version }, paths); + + assets.forEach((asset) => { + setArchiveEntry(asset.path, asset.content); + }); + + return paths; +}; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/fields.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/fields.ts new file mode 100644 index 0000000000000..059edae2f1b6d --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/fields.ts @@ -0,0 +1,292 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as yaml from 'js-yaml'; + +export const createBaseFields = () => { + const fields = [ + { name: 'data_stream.type', type: 'constant_keyword', description: 'Data stream type.' }, + { name: 'data_stream.dataset', type: 'constant_keyword', description: 'Data stream dataset.' }, + { + name: 'data_stream.namespace', + type: 'constant_keyword', + description: 'Data stream namespace.', + }, + { name: '@timestamp', type: 'date', description: 'Event timestamp.' }, + ]; + return yaml.dump(fields); +}; + +export const createAgentFields = () => { + const fields = [ + { + name: 'cloud', + title: 'Cloud', + group: 2, + description: 'Fields related to the cloud or infrastructure the events are coming from.', + footnote: + 'Examples: If Metricbeat is running on an EC2 host and fetches data from its host, the cloud info contains the data about this machine. If Metricbeat runs on a remote machine outside the cloud and fetches data from a service running in the cloud, the field contains cloud data from the machine the service is running on.', + type: 'group', + fields: [ + { + name: 'account.id', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: + 'The cloud account or organization id used to identify different entities in a multi-tenant environment.\nExamples: AWS account id, Google Cloud ORG Id, or other unique identifier.', + example: 666777888999, + }, + { + name: 'availability_zone', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Availability zone in which this host is running.', + example: 'us-east-1c', + }, + { + name: 'instance.id', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Instance ID of the host machine.', + example: 'i-1234567890abcdef0', + }, + { + name: 'instance.name', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Instance name of the host machine.', + }, + { + name: 'machine.type', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Machine type of the host machine.', + example: 't2.medium', + }, + { + name: 'provider', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: + 'Name of the cloud provider. Example values are aws, azure, gcp, or digitalocean.', + example: 'aws', + }, + { + name: 'region', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Region in which this host is running.', + example: 'us-east-1', + }, + { + name: 'project.id', + type: 'keyword', + description: 'Name of the project in Google Cloud.', + }, + { + name: 'image.id', + type: 'keyword', + description: 'Image ID for the cloud instance.', + }, + ], + }, + { + name: 'container', + title: 'Container', + group: 2, + description: + 'Container fields are used for meta information about the specific container that is the source of information.\nThese fields help correlate data based containers from any runtime.', + type: 'group', + fields: [ + { + name: 'id', + level: 'core', + type: 'keyword', + ignore_above: 1024, + description: 'Unique container id.', + }, + { + name: 'image.name', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Name of the image the container was built on.', + }, + { + name: 'labels', + level: 'extended', + type: 'object', + object_type: 'keyword', + description: 'Image labels.', + }, + { + name: 'name', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Container name.', + }, + ], + }, + { + name: 'host', + title: 'Host', + group: 2, + description: + 'A host is defined as a general computing instance.\nECS host.* fields should be populated with details about the host on which the event happened, or from which the measurement was taken. Host types include hardware, virtual machines, Docker containers, and Kubernetes nodes.', + type: 'group', + fields: [ + { + name: 'architecture', + level: 'core', + type: 'keyword', + ignore_above: 1024, + description: 'Operating system architecture.', + example: 'x86_64', + }, + { + name: 'domain', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: + "Name of the domain of which the host is a member.\nFor example, on Windows this could be the host's Active Directory domain or NetBIOS domain name. For Linux this could be the domain of the host's LDAP provider.", + example: 'CONTOSO', + default_field: false, + }, + { + name: 'hostname', + level: 'core', + type: 'keyword', + ignore_above: 1024, + description: + 'Hostname of the host.\nIt normally contains what the `hostname` command returns on the host machine', + }, + { + name: 'id', + level: 'core', + type: 'keyword', + ignore_above: 1024, + description: + 'Unique host id.\nAs hostname is not always unique, use values that are meaningful in your environment.\nExample: The current usage of `beat.name`', + }, + { + name: 'ip', + level: 'core', + type: 'ip', + description: 'Host ip addresses.', + }, + { + name: 'mac', + level: 'core', + type: 'keyword', + ignore_above: 1024, + description: 'Host mac addresses.', + }, + { + name: 'name', + level: 'core', + type: 'keyword', + ignore_above: 1024, + description: + 'Name of the host.\nIt can contain what `hostname` returns on Unix systems, the fully qualified domain name, or a name specified by the user. The sender decides which value to use', + }, + { + name: 'os.family', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'OS family (such as redhat, debian, freebsd, windows).', + example: 'debian', + }, + { + name: 'os.kernel', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Operating system kernel version as a raw string.', + example: '4.4.0-112-generic', + }, + { + name: 'os.name', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + multi_fields: [ + { + name: 'text', + type: 'text', + norms: false, + default_field: false, + }, + ], + description: 'Operating system name, without the version.', + example: 'Mac OS X', + }, + { + name: 'os.platform', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Operating system platform (such centos, ubuntu, windows).', + example: 'darwin', + }, + { + name: 'os.version', + level: 'extended', + type: 'keyword', + ignore_above: 1024, + description: 'Operating system version as a raw string.', + example: '10.14.1', + }, + { + name: 'type', + level: 'core', + type: 'keyword', + ignore_above: 1024, + description: + 'Type of host.\nFor Cloud providers this can be the machine type like `t2.medium`. If vm, this could be the container, for example, or other information meaningful in your environment', + }, + { + name: 'containerized', + type: 'boolean', + description: 'If the host is a container.\n', + }, + { + name: 'os.build', + type: 'keyword', + example: '18D109', + description: 'OS build information.\n', + }, + { + name: 'os.codename', + type: 'keyword', + example: 'stretch', + description: 'OS codename, if any.\n', + }, + ], + }, + { + name: 'input.type', + type: 'keyword', + description: 'Input type', + }, + { + name: 'log.offset', + type: 'long', + description: 'Log offset', + }, + ]; + return yaml.dump(fields); +}; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/index.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/index.ts new file mode 100644 index 0000000000000..76a7a6f6a089f --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './fields'; +export * from './manifest'; +export * from './utils'; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/ingest_pipeline.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/ingest_pipeline.ts new file mode 100644 index 0000000000000..0021f395158e6 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/ingest_pipeline.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as yaml from 'js-yaml'; + +// NOTE: The install methods will take care of adding a reference to a @custom pipeline. We don't need to add one here. +export const createDefaultPipeline = (dataset: string, type: string) => { + const pipeline = { + processors: [ + { + set: { + description: "If '@timestamp' is missing, set it with the ingest timestamp", + field: '@timestamp', + override: false, + copy_from: '_ingest.timestamp', + }, + }, + ], + _meta: { + description: `default pipeline for the ${dataset} dataset`, + managed: true, + }, + }; + return yaml.dump(pipeline); +}; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/manifest.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/manifest.ts new file mode 100644 index 0000000000000..75b34867f6d07 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/manifest.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import * as yaml from 'js-yaml'; + +import { convertStringToTitle } from '../../utils'; +import type { AssetOptions } from '../generate'; + +export const createDatasetManifest = (dataset: string, assetOptions: AssetOptions) => { + const { format_version: formatVersion, type } = assetOptions; + const manifest = { + format_version: formatVersion, + dataset, + title: convertStringToTitle(dataset), + type, + }; + return yaml.dump(manifest); +}; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/utils.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/utils.ts new file mode 100644 index 0000000000000..b984b8cddbbd3 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/dataset/utils.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CustomPackageDatasetConfiguration } from '../../../install'; + +export const generateDatastreamEntries = ( + datasets: CustomPackageDatasetConfiguration[], + packageName: string +) => { + return datasets.map((dataset) => { + const { name, type } = dataset; + return { + type, + dataset: `${packageName}.${name}`, + title: `Data stream for the ${packageName} custom integration, and ${name} dataset.`, + package: packageName, + path: name, + release: 'ga' as const, + // NOTE: This ensures our default.yml pipeline is used as the default_pipeline in the index template + ingest_pipeline: 'default', + }; + }); +}; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/generate.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/generate.ts new file mode 100644 index 0000000000000..a9063c76f7413 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/generate.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ArchivePackage } from '../../../../../../common'; + +import { pkgToPkgKey } from '../../../registry'; + +import type { CustomPackageDatasetConfiguration } from '../../install'; + +import { createAgentFields, createBaseFields, createDatasetManifest } from './dataset'; +import { createDefaultPipeline } from './dataset/ingest_pipeline'; +import { createManifest } from './manifest'; + +export type AssetOptions = ArchivePackage & { + kibanaVersion: string; + datasets: CustomPackageDatasetConfiguration[]; +}; + +// Mimic the use of an archive buffer via the same naming conventions +export const createAssets = (assetOptions: AssetOptions) => { + const { name, version, datasets } = assetOptions; + return [ + { + path: `${pkgToPkgKey({ name, version })}/manifest.yml`, + content: Buffer.from(createManifest(assetOptions)), + }, + ...datasets + .map((datasetConfiguration) => { + const { name: datasetName, type: datasetType } = datasetConfiguration; + return [ + { + path: `${pkgToPkgKey({ name, version })}/data_stream/${datasetName}/manifest.yml`, + content: Buffer.from(createDatasetManifest(datasetName, assetOptions)), + }, + // NOTE: buildDefaultSettings() will add a reference to the global ILM policy when + // building the index template based on the fields assets. + { + path: `${pkgToPkgKey({ + name, + version, + })}/data_stream/${datasetName}/fields/base-fields.yml`, + content: Buffer.from(createBaseFields()), + }, + { + path: `${pkgToPkgKey({ name, version })}/data_stream/${datasetName}/fields/agent.yml`, + content: Buffer.from(createAgentFields()), + }, + { + path: `${pkgToPkgKey({ + name, + version, + })}/data_stream/${datasetName}/elasticsearch/ingest_pipeline/default.yml`, + content: Buffer.from(createDefaultPipeline(datasetName, datasetType)), + }, + ]; + }) + .flat(), + ]; +}; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/index.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/index.ts new file mode 100644 index 0000000000000..a1e8ed713e97f --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './generate'; +export * from './manifest'; +export * from './dataset'; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/manifest.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/manifest.ts new file mode 100644 index 0000000000000..cf308f03db7dd --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/assets/manifest.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import * as yaml from 'js-yaml'; + +import type { AssetOptions } from './generate'; + +export const createManifest = (assetOptions: AssetOptions) => { + const { + format_version: formatVersion, + name, + title, + description, + version, + owner, + kibanaVersion, + } = assetOptions; + + const manifest = { + format_version: formatVersion, + name, + title, + description, + version, + owner, + type: 'integration' as const, + conditions: { + kibana: { + version: kibanaVersion, + }, + }, + }; + + return yaml.dump(manifest); +}; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/constants.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/constants.ts new file mode 100644 index 0000000000000..89ef9105b5905 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/constants.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const INITIAL_VERSION = '1.0.0'; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/index.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/index.ts new file mode 100644 index 0000000000000..8065d42e3bef2 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './assets'; +export * from './constants'; +export * from './utils'; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/utils.ts b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/utils.ts new file mode 100644 index 0000000000000..d90c12d231f74 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/epm/packages/custom_integrations/utils.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const convertStringToTitle = (name: string) => { + return name + .split('_') + .map((word) => { + return word[0].toUpperCase() + word.substring(1); + }) + .join(' '); +}; + +export const generateDescription = (datasetNames: string[]) => + `Collect logs for the datasets: ${datasetNames.join(', ')}`; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index a911507b2aad8..2efb841b75f3b 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -25,6 +25,8 @@ import { uniqBy } from 'lodash'; import type { LicenseType } from '@kbn/licensing-plugin/server'; +import type { PackageDataStreamTypes } from '../../../../common/types'; + import type { HTTPAuthorizationHeader } from '../../../../common/http_authorization_header'; import { isPackagePrerelease, getNormalizedDataStreams } from '../../../../common/services'; @@ -49,7 +51,11 @@ import type { PackageVerificationResult, RegistryDataStream, } from '../../../types'; -import { AUTO_UPGRADE_POLICIES_PACKAGES, DATASET_VAR_NAME } from '../../../../common/constants'; +import { + AUTO_UPGRADE_POLICIES_PACKAGES, + CUSTOM_INTEGRATION_PACKAGE_SPEC_VERSION, + DATASET_VAR_NAME, +} from '../../../../common/constants'; import { type FleetError, PackageOutdatedError, @@ -91,6 +97,11 @@ import { _installPackage } from './_install_package'; import { removeOldAssets } from './cleanup'; import { getBundledPackages } from './bundled_packages'; import { withPackageSpan } from './utils'; +import { convertStringToTitle, generateDescription } from './custom_integrations/utils'; +import { INITIAL_VERSION } from './custom_integrations/constants'; +import { createAssets } from './custom_integrations'; +import { cacheAssets } from './custom_integrations/assets/cache'; +import { generateDatastreamEntries } from './custom_integrations/assets/dataset/utils'; export async function isPackageInstalled(options: { savedObjectsClient: SavedObjectsClientContract; @@ -288,6 +299,21 @@ interface InstallRegistryPackageParams { prerelease?: boolean; authorizationHeader?: HTTPAuthorizationHeader | null; } + +export interface CustomPackageDatasetConfiguration { + name: string; + type: PackageDataStreamTypes; +} +interface InstallCustomPackageParams { + savedObjectsClient: SavedObjectsClientContract; + pkgName: string; + datasets: CustomPackageDatasetConfiguration[]; + esClient: ElasticsearchClient; + spaceId: string; + force?: boolean; + authorizationHeader?: HTTPAuthorizationHeader | null; + kibanaVersion: string; +} interface InstallUploadedArchiveParams { savedObjectsClient: SavedObjectsClientContract; esClient: ElasticsearchClient; @@ -424,7 +450,7 @@ function getElasticSubscription(packageInfo: ArchivePackage) { async function installPackageCommon(options: { pkgName: string; pkgVersion: string; - installSource: 'registry' | 'upload'; + installSource: 'registry' | 'upload' | 'custom'; installedPkg?: SavedObject; installType: InstallType; savedObjectsClient: SavedObjectsClientContract; @@ -659,6 +685,7 @@ export type InstallPackageParams = { | ({ installSource: Extract } & InstallRegistryPackageParams) | ({ installSource: Extract } & InstallUploadedArchiveParams) | ({ installSource: Extract } & InstallUploadedArchiveParams) + | ({ installSource: Extract } & InstallCustomPackageParams) ); export async function installPackage(args: InstallPackageParams): Promise { @@ -723,10 +750,72 @@ export async function installPackage(args: InstallPackageParams): Promise { + const { + savedObjectsClient, + esClient, + spaceId, + pkgName, + force, + authorizationHeader, + datasets, + kibanaVersion, + } = args; + + // Compose a packageInfo + const packageInfo = { + format_version: CUSTOM_INTEGRATION_PACKAGE_SPEC_VERSION, + name: pkgName, + title: convertStringToTitle(pkgName), + description: generateDescription(datasets.map((dataset) => dataset.name)), + version: INITIAL_VERSION, + owner: { github: authorizationHeader?.username ?? 'unknown' }, + type: 'integration' as const, + data_streams: generateDatastreamEntries(datasets, pkgName), + }; + + const assets = createAssets({ + ...packageInfo, + kibanaVersion, + datasets, + }); + + const paths = cacheAssets(assets, pkgName, INITIAL_VERSION); + + return await installPackageCommon({ + pkgName, + pkgVersion: INITIAL_VERSION, + installSource: 'custom', + installType: 'install', + savedObjectsClient, + esClient, + spaceId, + force, + packageInfo, + paths, + authorizationHeader, + }); +} + export const updateVersion = async ( savedObjectsClient: SavedObjectsClientContract, pkgName: string, diff --git a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts index cecd177b0225b..09a20ebca45b2 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/epm.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/epm.ts @@ -194,6 +194,25 @@ export const InstallPackageByUploadRequestSchema = { body: schema.buffer(), }; +export const CreateCustomIntegrationRequestSchema = { + body: schema.object({ + integrationName: schema.string(), + datasets: schema.arrayOf( + schema.object({ + name: schema.string(), + type: schema.oneOf([ + schema.literal('logs'), + schema.literal('metrics'), + schema.literal('traces'), + schema.literal('synthetics'), + schema.literal('profiling'), + ]), + }) + ), + force: schema.maybe(schema.boolean()), + }), +}; + export const DeletePackageRequestSchema = { params: schema.object({ pkgName: schema.string(), diff --git a/x-pack/test/fleet_api_integration/apis/epm/index.js b/x-pack/test/fleet_api_integration/apis/epm/index.js index 2fa0c0c881a59..045626e95a740 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/index.js +++ b/x-pack/test/fleet_api_integration/apis/epm/index.js @@ -21,6 +21,7 @@ export default function loadTests({ loadTestFile, getService }) { loadTestFile(require.resolve('./ilm')); loadTestFile(require.resolve('./install_bundled')); loadTestFile(require.resolve('./install_by_upload')); + loadTestFile(require.resolve('./install_custom')); loadTestFile(require.resolve('./install_endpoint')); loadTestFile(require.resolve('./install_overrides')); loadTestFile(require.resolve('./install_prerelease')); diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_custom.ts b/x-pack/test/fleet_api_integration/apis/epm/install_custom.ts new file mode 100644 index 0000000000000..492d708da5ef7 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/epm/install_custom.ts @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { PACKAGES_SAVED_OBJECT_TYPE } from '@kbn/fleet-plugin/common'; + +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; + +const INTEGRATION_NAME = 'my_custom_nginx'; +const INTEGRATION_VERSION = '1.0.0'; + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const supertest = getService('supertest'); + const kibanaServer = getService('kibanaServer'); + + const uninstallPackage = async () => { + await supertest + .delete(`/api/fleet/epm/packages/${INTEGRATION_NAME}/${INTEGRATION_VERSION}`) + .set('kbn-xsrf', 'xxxx'); + }; + + describe('Installing custom integrations', async () => { + afterEach(async () => { + await uninstallPackage(); + }); + + it("Correcty installs a custom integration and all of it's assets", async () => { + const response = await supertest + .post(`/api/fleet/epm/custom_integrations`) + .set('kbn-xsrf', 'xxxx') + .type('application/json') + .send({ + force: true, + integrationName: 'my_custom_nginx', + datasets: [ + { name: 'access', type: 'logs' }, + { name: 'error', type: 'metrics' }, + { name: 'warning', type: 'logs' }, + ], + }) + .expect(200); + + const expectedIngestPipelines = [ + 'logs-my_custom_nginx.access-1.0.0', + 'metrics-my_custom_nginx.error-1.0.0', + 'logs-my_custom_nginx.warning-1.0.0', + ]; + const expectedIndexTemplates = [ + 'logs-my_custom_nginx.access', + 'metrics-my_custom_nginx.error', + 'logs-my_custom_nginx.warning', + ]; + const expectedComponentTemplates = [ + 'logs-my_custom_nginx.access@package', + 'logs-my_custom_nginx.access@custom', + 'metrics-my_custom_nginx.error@package', + 'metrics-my_custom_nginx.error@custom', + 'logs-my_custom_nginx.warning@package', + 'logs-my_custom_nginx.warning@custom', + ]; + + expect(response.body._meta.install_source).to.be('custom'); + + const actualIngestPipelines = response.body.items + .filter((item: any) => item.type === 'ingest_pipeline') + .map((pipeline: any) => pipeline.id); + + const actualIndexTemplates = response.body.items + .filter((item: any) => item.type === 'index_template') + .map((template: any) => template.id); + + const actualComponentTemplates = response.body.items + .filter((item: any) => item.type === 'component_template') + .map((template: any) => template.id); + + expectedIngestPipelines.forEach((pipeline) => { + expect(actualIngestPipelines).to.contain(pipeline); + }); + expectedIndexTemplates.forEach((template) => { + expect(actualIndexTemplates).to.contain(template); + }); + expectedComponentTemplates.forEach((template) => { + expect(actualComponentTemplates).to.contain(template); + }); + + const installation = await kibanaServer.savedObjects.get({ + type: PACKAGES_SAVED_OBJECT_TYPE, + id: INTEGRATION_NAME, + }); + + expect(installation.attributes.name).to.be(INTEGRATION_NAME); + expect(installation.attributes.version).to.be(INTEGRATION_VERSION); + expect(installation.attributes.install_source).to.be('custom'); + expect(installation.attributes.install_status).to.be('installed'); + }); + }); +} From c8a451e45a6443263cc8807826dcb64a029f7591 Mon Sep 17 00:00:00 2001 From: jennypavlova Date: Thu, 13 Jul 2023 12:13:53 +0200 Subject: [PATCH 95/97] [Infra UI] Test fix: add retry to metadata remove pin button check after refresh (#161736) Closes #161514 ## Summary This PR fixes the flyout test, it seems there was a timeout before the check (in the screenshot is visible that the button is there so could be that the check happened before the loading finished) I added a retry there. --- x-pack/test/functional/apps/infra/hosts_view.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/test/functional/apps/infra/hosts_view.ts b/x-pack/test/functional/apps/infra/hosts_view.ts index 0e417d6306c5b..1cb551fa91247 100644 --- a/x-pack/test/functional/apps/infra/hosts_view.ts +++ b/x-pack/test/functional/apps/infra/hosts_view.ts @@ -154,8 +154,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { return !!currentUrl.match(path); }); - // Failing: See https://github.com/elastic/kibana/issues/161514 - describe.skip('Hosts View', function () { + describe('Hosts View', function () { before(async () => { await Promise.all([ esArchiver.load('x-pack/test/functional/es_archives/infra/alerts'), @@ -309,8 +308,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { // Persist pin after refresh await browser.refresh(); - await pageObjects.infraHome.waitForLoading(); - expect(await pageObjects.infraHostsView.getRemovePinExist()).to.be(true); + await retry.try(async () => { + await pageObjects.infraHome.waitForLoading(); + const removePinExist = await pageObjects.infraHostsView.getRemovePinExist(); + expect(removePinExist).to.be(true); + }); // Remove Pin await pageObjects.infraHostsView.clickRemoveMetadataPin(); From 808c28dd8eeb8f5fb0916c9944266bc8ebdf0302 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Thu, 13 Jul 2023 12:22:02 +0200 Subject: [PATCH 96/97] Migrate from deprecated EUI components (#161548) ## Summary Fix https://github.com/elastic/kibana/issues/161424 Migrate away from deprecated EUI components for Core-owned code. Note: I only tested the production (and examples) pages properly, I didn't make sure the test plugins where displayed correctly, as long as the data structure was still here for the tests to pass. ### Screenshots #### Status page Screenshot 2023-07-10 at 17 14 24 #### AppNotFound page Screenshot 2023-07-10 at 17 14 40 #### Generated plugin landing page Screenshot 2023-07-10 at 17 15 44 --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- examples/preboot_example/public/app.tsx | 266 +++++++++--------- examples/routing_example/public/app.tsx | 28 +- .../src/ui/app_not_found_screen.tsx | 55 ++-- .../src/errors/error_application.tsx | 27 +- .../src/status/components/status_section.tsx | 12 +- .../src/status/components/version_header.tsx | 11 +- .../fatal_errors_screen.test.tsx.snap | 8 +- .../src/fatal_errors_screen.tsx | 8 +- .../template/public/components/app.tsx.ejs | 110 ++++---- .../public/app/components/main.tsx | 13 +- .../core_app_status/public/application.tsx | 23 +- .../core_plugin_a/public/application.tsx | 47 ++-- .../public/application.tsx | 23 +- .../core_plugin_b/public/application.tsx | 51 ++-- .../public/application.tsx | 23 +- .../public/application.tsx | 65 ++--- .../public/application.tsx | 23 +- 17 files changed, 346 insertions(+), 447 deletions(-) diff --git a/examples/preboot_example/public/app.tsx b/examples/preboot_example/public/app.tsx index 10d5cfd57a06e..2c80565f259ea 100644 --- a/examples/preboot_example/public/app.tsx +++ b/examples/preboot_example/public/app.tsx @@ -12,7 +12,7 @@ import { EuiFieldText, EuiFlexGroup, EuiFlexItem, - EuiPageTemplate_Deprecated as EuiPageTemplate, + EuiPageTemplate, EuiPanel, EuiText, } from '@elastic/eui'; @@ -73,147 +73,139 @@ export const App = ({ http, token }: { http: HttpSetup; token?: string }) => { if (!isSetupModeActive) { return ( - - - Kibana server is not ready yet. - + + + + + Kibana server is not ready yet. + + ); } return ( - - - - - - - { - setConfigKeyValue({ ...configKeyValue, key: e.target.value }); - }} - /> - - - { - setConfigKeyValue({ ...configKeyValue, value: e.target.value }); - }} - /> - - - - Write config - - - - - - - - Token from config: {token} - - - onCompleteSetup({ shouldReloadConfig: true })} - > - Reload config and proceed to `setup` - - - - onCompleteSetup({ shouldReloadConfig: false })} - > - DO NOT reload config and proceed to `setup` - - - - - - - - { - setElasticsearchConfig({ ...elasticsearchConfig, host: e.target.value }); - }} - /> - - - { - setElasticsearchConfig({ - ...elasticsearchConfig, - username: e.target.value, - }); - }} - /> - - - { - setElasticsearchConfig({ - ...elasticsearchConfig, - password: e.target.value, - }); - }} - /> - - - - Connect - - - - - - - {connectResponse ?? ''} - - - - + + + + + + + + + { + setConfigKeyValue({ ...configKeyValue, key: e.target.value }); + }} + /> + + + { + setConfigKeyValue({ ...configKeyValue, value: e.target.value }); + }} + /> + + + + Write config + + + + + + + + Token from config: {token} + + + onCompleteSetup({ shouldReloadConfig: true })} + > + Reload config and proceed to `setup` + + + + onCompleteSetup({ shouldReloadConfig: false })} + > + DO NOT reload config and proceed to `setup` + + + + + + + + { + setElasticsearchConfig({ ...elasticsearchConfig, host: e.target.value }); + }} + /> + + + { + setElasticsearchConfig({ + ...elasticsearchConfig, + username: e.target.value, + }); + }} + /> + + + { + setElasticsearchConfig({ + ...elasticsearchConfig, + password: e.target.value, + }); + }} + /> + + + + Connect + + + + + + + {connectResponse ?? ''} + + + + + ); }; diff --git a/examples/routing_example/public/app.tsx b/examples/routing_example/public/app.tsx index 51389ae913424..eb9589919d2ab 100644 --- a/examples/routing_example/public/app.tsx +++ b/examples/routing_example/public/app.tsx @@ -10,12 +10,10 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { AppMountParameters } from '@kbn/core/public'; import { - EuiPage, - EuiPageBody, - EuiPageContent_Deprecated as EuiPageContent, + EuiPageTemplate, + EuiPageSection, EuiText, EuiHorizontalRule, - EuiPageContentHeader_Deprecated as EuiPageContentHeader, EuiListGroup, } from '@elastic/eui'; import { RandomNumberRouteExample } from './random_number_example'; @@ -34,14 +32,14 @@ function RoutingExplorer({ getMessageById, }: Props) { return ( - - - - - -

Routing examples

-
-
+ + + +

Routing examples

+
+
+ + -
-
-
+ + +
); } diff --git a/packages/core/application/core-application-browser-internal/src/ui/app_not_found_screen.tsx b/packages/core/application/core-application-browser-internal/src/ui/app_not_found_screen.tsx index b986afd988d5b..6842a675dc0da 100644 --- a/packages/core/application/core-application-browser-internal/src/ui/app_not_found_screen.tsx +++ b/packages/core/application/core-application-browser-internal/src/ui/app_not_found_screen.tsx @@ -6,40 +6,31 @@ * Side Public License, v 1. */ -import { - EuiEmptyPrompt, - EuiPage, - EuiPageBody, - EuiPageContent_Deprecated as EuiPageContent, -} from '@elastic/eui'; +import { EuiPageTemplate } from '@elastic/eui'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; export const AppNotFound = () => ( - - - - - - - } - body={ -

- -

- } - /> -
-
-
+ + + + + } + body={ +

+ +

+ } + /> +
); diff --git a/packages/core/apps/core-apps-browser-internal/src/errors/error_application.tsx b/packages/core/apps/core-apps-browser-internal/src/errors/error_application.tsx index 32a3d83d40413..02ef568f18302 100644 --- a/packages/core/apps/core-apps-browser-internal/src/errors/error_application.tsx +++ b/packages/core/apps/core-apps-browser-internal/src/errors/error_application.tsx @@ -12,12 +12,7 @@ import type { History } from 'history'; import { i18n } from '@kbn/i18n'; import { I18nProvider } from '@kbn/i18n-react'; -import { - EuiEmptyPrompt, - EuiPage, - EuiPageBody, - EuiPageContent_Deprecated as EuiPageContent, -} from '@elastic/eui'; +import { EuiPageTemplate } from '@elastic/eui'; import { CoreThemeProvider } from '@kbn/core-theme-browser-internal'; import type { IBasePath } from '@kbn/core-http-browser'; import type { AppMountParameters } from '@kbn/core-application-browser'; @@ -36,18 +31,14 @@ const ErrorPage: React.FC = ({ title, children }) => { }); return ( - - - - {title}} - body={children} - /> - - - + + {title}} + body={children} + /> + ); }; diff --git a/packages/core/apps/core-apps-browser-internal/src/status/components/status_section.tsx b/packages/core/apps/core-apps-browser-internal/src/status/components/status_section.tsx index 15a5f65be59b1..afceaccc76b98 100644 --- a/packages/core/apps/core-apps-browser-internal/src/status/components/status_section.tsx +++ b/packages/core/apps/core-apps-browser-internal/src/status/components/status_section.tsx @@ -7,13 +7,7 @@ */ import React, { FC, useMemo } from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiPageContent_Deprecated as EuiPageContent, - EuiSpacer, - EuiTitle, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle, EuiPanel } from '@elastic/eui'; import { StatusTable } from './status_table'; import { FormattedStatus, getHighestStatus } from '../lib'; import { StatusBadge } from './status_badge'; @@ -28,7 +22,7 @@ export const StatusSection: FC = ({ id, title, statuses }) = const highestStatus = useMemo(() => getHighestStatus(statuses), [statuses]); return ( - + @@ -41,6 +35,6 @@ export const StatusSection: FC = ({ id, title, statuses }) = - +
); }; diff --git a/packages/core/apps/core-apps-browser-internal/src/status/components/version_header.tsx b/packages/core/apps/core-apps-browser-internal/src/status/components/version_header.tsx index 81b76f771cda1..6eeb78cacd9d3 100644 --- a/packages/core/apps/core-apps-browser-internal/src/status/components/version_header.tsx +++ b/packages/core/apps/core-apps-browser-internal/src/status/components/version_header.tsx @@ -7,12 +7,7 @@ */ import React, { FC } from 'react'; -import { - EuiFlexGroup, - EuiFlexItem, - EuiPageContent_Deprecated as EuiPageContent, - EuiText, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import type { ServerVersion } from '@kbn/core-status-common-internal'; @@ -23,7 +18,7 @@ interface VersionHeaderProps { export const VersionHeader: FC = ({ version }) => { const { build_hash: buildHash, build_number: buildNumber, number } = version; return ( - + @@ -65,6 +60,6 @@ export const VersionHeader: FC = ({ version }) => { - +
); }; diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/__snapshots__/fatal_errors_screen.test.tsx.snap b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/__snapshots__/fatal_errors_screen.test.tsx.snap index a2163e2b4c4e9..48caf45f0b0f1 100644 --- a/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/__snapshots__/fatal_errors_screen.test.tsx.snap +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/__snapshots__/fatal_errors_screen.test.tsx.snap @@ -4,14 +4,14 @@ exports[`FatalErrorsScreen rendering render matches snapshot 1`] = ` - - + `; diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.tsx b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.tsx index a7f274920694f..69ed16c0377b0 100644 --- a/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.tsx +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.tsx @@ -14,7 +14,7 @@ import { EuiEmptyPrompt, EuiPage, EuiPageBody, - EuiPageContent_Deprecated as EuiPageContent, + EuiPageSection, } from '@elastic/eui'; import React from 'react'; import { Observable, Subscription, merge, tap, fromEvent } from 'rxjs'; @@ -75,9 +75,9 @@ export class FatalErrorsScreen extends React.Component { public render() { return ( - + - + { ))} - + ); diff --git a/packages/kbn-plugin-generator/template/public/components/app.tsx.ejs b/packages/kbn-plugin-generator/template/public/components/app.tsx.ejs index 12303d9ff0465..5702d69fba3b6 100644 --- a/packages/kbn-plugin-generator/template/public/components/app.tsx.ejs +++ b/packages/kbn-plugin-generator/template/public/components/app.tsx.ejs @@ -2,23 +2,15 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage, I18nProvider } from '@kbn/i18n-react'; import { BrowserRouter as Router } from '@kbn/shared-ux-router'; - - import { EuiButton, EuiHorizontalRule, - EuiPage, - EuiPageBody, - EuiPageContent_Deprecated as EuiPageContent, - EuiPageContentBody_Deprecated as EuiPageContentBody, - EuiPageContentHeader_Deprecated as EuiPageContentHeader, - EuiPageHeader, + EuiPageTemplate, EuiTitle, EuiText, } from '@elastic/eui'; - -import { CoreStart } from '<%= importFromRoot('src/core/public') %>'; -import { NavigationPublicPluginStart } from '<%= importFromRoot('src/plugins/navigation/public') %>'; +import type { CoreStart } from '@kbn/core/public'; +import type { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public'; import { PLUGIN_ID, PLUGIN_NAME } from '../../common'; @@ -56,57 +48,51 @@ export const <%= upperCamelCase(name) %>App = ({ basename, notifications, http, <> - - - - -

- -

-
-
- - - -

- -

-
-
- - -

- -

- -

- -

- - - -
-
-
-
-
+ + + +

+ +

+
+
+ + +

+ +

+
+ +

+ +

+ +

+ +

+ + + +
+
+
diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app/components/main.tsx b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app/components/main.tsx index 353f1b71c2261..60db69514f81f 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app/components/main.tsx +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/app/components/main.tsx @@ -8,12 +8,7 @@ import './main.scss'; import React from 'react'; -import { - EuiPage, - EuiPageBody, - EuiPageContent_Deprecated as EuiPageContent, - EuiPageContentHeader_Deprecated as EuiPageContentHeader, -} from '@elastic/eui'; +import { EuiPage, EuiPageBody, EuiPageSection, EuiPageHeader } from '@elastic/eui'; import { first, pluck } from 'rxjs/operators'; import { IInterpreterRenderHandlers, ExpressionValue } from '@kbn/expressions-plugin/public'; import { ExpressionRenderHandler } from '../../types'; @@ -89,11 +84,11 @@ class Main extends React.Component<{}, State> { return ( - - runPipeline tests are running ... + + runPipeline tests are running ...
{this.state.expression}
- + ); diff --git a/test/plugin_functional/plugins/core_app_status/public/application.tsx b/test/plugin_functional/plugins/core_app_status/public/application.tsx index f82a558f3a471..3ea989dfbf1d2 100644 --- a/test/plugin_functional/plugins/core_app_status/public/application.tsx +++ b/test/plugin_functional/plugins/core_app_status/public/application.tsx @@ -11,10 +11,7 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { EuiPage, EuiPageBody, - EuiPageContent_Deprecated as EuiPageContent, - EuiPageContentBody_Deprecated as EuiPageContentBody, - EuiPageContentHeader_Deprecated as EuiPageContentHeader, - EuiPageContentHeaderSection_Deprecated as EuiPageContentHeaderSection, + EuiPageSection, EuiPageHeader, EuiPageHeaderSection, EuiTitle, @@ -32,16 +29,14 @@ const AppStatusApp = ({ appId }: { appId: string }) => ( - - - - -

{appId} Test App home page section title

-
-
-
- {appId} Test App content -
+ + + +

{appId} Test App home page section title

+
+
+ {appId} Test App content +
); diff --git a/test/plugin_functional/plugins/core_plugin_a/public/application.tsx b/test/plugin_functional/plugins/core_plugin_a/public/application.tsx index a896e918f4d53..6c1440c10abf2 100644 --- a/test/plugin_functional/plugins/core_plugin_a/public/application.tsx +++ b/test/plugin_functional/plugins/core_plugin_a/public/application.tsx @@ -15,13 +15,10 @@ import { Router, Route } from '@kbn/shared-ux-router'; import { EuiPage, EuiPageBody, - EuiPageContent_Deprecated as EuiPageContent, - EuiPageContentBody_Deprecated as EuiPageContentBody, - EuiPageContentHeader_Deprecated as EuiPageContentHeader, - EuiPageContentHeaderSection_Deprecated as EuiPageContentHeaderSection, + EuiPageSection, EuiPageHeader, EuiPageHeaderSection, - EuiPageSideBar_Deprecated as EuiPageSideBar, + EuiPageSidebar, EuiTitle, EuiSideNav, } from '@elastic/eui'; @@ -37,16 +34,14 @@ const Home = () => ( - - - - -

Bar home page section title

-
-
-
- Wow what a home page this is! -
+ + + +

Bar home page section title

+
+
+ Wow what a home page this is! +
); @@ -59,16 +54,14 @@ const PageA = () => ( - - - - -

Page A section title

-
-
-
- Page A's content goes here -
+ + + +

Page A section title

+
+
+ Page A's content goes here +
); @@ -109,9 +102,9 @@ const Nav = withRouter(({ history, navigateToApp }: NavProps) => ( const FooApp = ({ history, coreStart }: { history: History; coreStart: CoreStart }) => ( - +