From abf6a1d4f6e83f108ed11a3e6279d73db514b352 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 11 Nov 2024 17:50:29 -0800 Subject: [PATCH 001/105] [Inference Connector] Modified getProvider to use _inference/_services ES API instead of hardcoded values. (#199047) @ymao1 [introduced](https://github.com/elastic/elasticsearch/pull/114862) new ES API which allows to fetch available services providers list with the settings and task types: `GET _inference/_services` This PR is changing hardcoded providers list `x-pack/plugins/stack_connectors/public/connector_types/inference/providers/get_providers.ts` to use new ES API. --- .../lib => common}/dynamic_config/types.ts | 0 .../common/inference/types.ts | 15 + .../inference/additional_options_fields.tsx | 4 +- .../inference/connector.test.tsx | 75 +- .../connector_types/inference/connector.tsx | 59 +- .../inference/get_task_types.test.ts | 50 - .../inference/get_task_types.ts | 606 ---------- .../connector_types/inference/helpers.ts | 2 +- .../inference/hidden_fields.tsx | 2 +- .../inference/providers/get_providers.ts | 1022 +---------------- .../service_provider.tsx | 6 +- .../inference/providers/selectable/index.tsx | 23 +- .../public/connector_types/inference/types.ts | 3 - .../connector_configuration_field.tsx | 2 +- .../connector_configuration_form_items.tsx | 2 +- .../connector_configuration_utils.ts | 2 +- .../plugins/stack_connectors/server/plugin.ts | 7 +- .../routes/get_inference_services.test.ts | 133 +++ .../server/routes/get_inference_services.ts | 48 + .../stack_connectors/server/routes/index.ts | 1 + 20 files changed, 301 insertions(+), 1761 deletions(-) rename x-pack/plugins/stack_connectors/{public/connector_types/lib => common}/dynamic_config/types.ts (100%) delete mode 100644 x-pack/plugins/stack_connectors/public/connector_types/inference/get_task_types.test.ts delete mode 100644 x-pack/plugins/stack_connectors/public/connector_types/inference/get_task_types.ts create mode 100644 x-pack/plugins/stack_connectors/server/routes/get_inference_services.test.ts create mode 100644 x-pack/plugins/stack_connectors/server/routes/get_inference_services.ts diff --git a/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/types.ts b/x-pack/plugins/stack_connectors/common/dynamic_config/types.ts similarity index 100% rename from x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/types.ts rename to x-pack/plugins/stack_connectors/common/dynamic_config/types.ts diff --git a/x-pack/plugins/stack_connectors/common/inference/types.ts b/x-pack/plugins/stack_connectors/common/inference/types.ts index 9dbd447cb4578..b9561efe24292 100644 --- a/x-pack/plugins/stack_connectors/common/inference/types.ts +++ b/x-pack/plugins/stack_connectors/common/inference/types.ts @@ -19,6 +19,7 @@ import { TextEmbeddingParamsSchema, TextEmbeddingResponseSchema, } from './schema'; +import { ConfigProperties } from '../dynamic_config/types'; export type Config = TypeOf; export type Secrets = TypeOf; @@ -36,3 +37,17 @@ export type TextEmbeddingParams = TypeOf; export type TextEmbeddingResponse = TypeOf; export type StreamingResponse = TypeOf; + +export type FieldsConfiguration = Record; + +export interface InferenceTaskType { + task_type: string; + configuration: FieldsConfiguration; +} + +export interface InferenceProvider { + provider: string; + task_types: InferenceTaskType[]; + logo?: string; + configuration: FieldsConfiguration; +} diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/additional_options_fields.tsx b/x-pack/plugins/stack_connectors/public/connector_types/inference/additional_options_fields.tsx index 8973f3124bc86..7a3b1abfd800b 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/additional_options_fields.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/inference/additional_options_fields.tsx @@ -32,10 +32,10 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import { fieldValidators } from '@kbn/es-ui-shared-plugin/static/forms/helpers'; +import { ConfigEntryView } from '../../../common/dynamic_config/types'; import { ConnectorConfigurationFormItems } from '../lib/dynamic_config/connector_configuration_form_items'; import * as i18n from './translations'; import { DEFAULT_TASK_TYPE } from './constants'; -import { ConfigEntryView } from '../lib/dynamic_config/types'; import { Config } from './types'; import { TaskTypeOption } from './helpers'; @@ -52,7 +52,7 @@ interface AdditionalOptionsConnectorFieldsProps { isEdit: boolean; optionalProviderFormFields: ConfigEntryView[]; onSetProviderConfigEntry: (key: string, value: unknown) => Promise; - onTaskTypeOptionsSelect: (taskType: string, provider?: string) => Promise; + onTaskTypeOptionsSelect: (taskType: string, provider?: string) => void; selectedTaskType?: string; taskTypeFormFields: ConfigEntryView[]; taskTypeSchema: ConfigEntryView[]; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/connector.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/inference/connector.test.tsx index 44632e8b08331..d445504011b5f 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/connector.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/inference/connector.test.tsx @@ -12,13 +12,10 @@ import { ConnectorFormTestProvider } from '../lib/test_utils'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { createStartServicesMock } from '@kbn/triggers-actions-ui-plugin/public/common/lib/kibana/kibana_react.mock'; -import { DisplayType, FieldType } from '../lib/dynamic_config/types'; import { useProviders } from './providers/get_providers'; -import { getTaskTypes } from './get_task_types'; -import { HttpSetup } from '@kbn/core-http-browser'; +import { DisplayType, FieldType } from '../../../common/dynamic_config/types'; jest.mock('./providers/get_providers'); -jest.mock('./get_task_types'); const mockUseKibanaReturnValue = createStartServicesMock(); jest.mock('@kbn/triggers-actions-ui-plugin/public/common/lib/kibana', () => ({ @@ -37,13 +34,32 @@ jest.mock('@faker-js/faker', () => ({ })); const mockProviders = useProviders as jest.Mock; -const mockTaskTypes = getTaskTypes as jest.Mock; const providersSchemas = [ { provider: 'openai', logo: '', // should be openai logo here, the hardcoded uses assets/images - taskTypes: ['completion', 'text_embedding'], + task_types: [ + { + task_type: 'completion', + configuration: { + user: { + display: DisplayType.TEXTBOX, + label: 'User', + order: 1, + required: false, + sensitive: false, + tooltip: 'Specifies the user issuing the request.', + type: FieldType.STRING, + validations: [], + value: '', + ui_restrictions: [], + default_value: null, + depends_on: [], + }, + }, + }, + ], configuration: { api_key: { display: DisplayType.TEXTBOX, @@ -106,7 +122,16 @@ const providersSchemas = [ { provider: 'googleaistudio', logo: '', // should be googleaistudio logo here, the hardcoded uses assets/images - taskTypes: ['completion', 'text_embedding'], + task_types: [ + { + task_type: 'completion', + configuration: {}, + }, + { + task_type: 'text_embedding', + configuration: {}, + }, + ], configuration: { api_key: { display: DisplayType.TEXTBOX, @@ -139,39 +164,6 @@ const providersSchemas = [ }, }, ]; -const taskTypesSchemas: Record = { - googleaistudio: [ - { - task_type: 'completion', - configuration: {}, - }, - { - task_type: 'text_embedding', - configuration: {}, - }, - ], - openai: [ - { - task_type: 'completion', - configuration: { - user: { - display: DisplayType.TEXTBOX, - label: 'User', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the user issuing the request.', - type: FieldType.STRING, - validations: [], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - ], -}; const openAiConnector = { actionTypeId: '.inference', @@ -222,9 +214,6 @@ describe('ConnectorFields renders', () => { isLoading: false, data: providersSchemas, }); - mockTaskTypes.mockImplementation( - (http: HttpSetup, provider: string) => taskTypesSchemas[provider] - ); }); test('openai provider fields are rendered', async () => { const { getAllByTestId } = render( diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/connector.tsx b/x-pack/plugins/stack_connectors/public/connector_types/inference/connector.tsx index 35314dc06167d..5f854384dbb54 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/connector.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/inference/connector.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState, useEffect, useCallback } from 'react'; +import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { EuiFormRow, EuiSpacer, @@ -31,12 +31,12 @@ import { import { useKibana } from '@kbn/triggers-actions-ui-plugin/public'; import { fieldValidators } from '@kbn/es-ui-shared-plugin/static/forms/helpers'; +import { ConfigEntryView } from '../../../common/dynamic_config/types'; +import { InferenceTaskType } from '../../../common/inference/types'; import { ServiceProviderKeys } from '../../../common/inference/constants'; import { ConnectorConfigurationFormItems } from '../lib/dynamic_config/connector_configuration_form_items'; -import { getTaskTypes } from './get_task_types'; import * as i18n from './translations'; import { DEFAULT_TASK_TYPE } from './constants'; -import { ConfigEntryView } from '../lib/dynamic_config/types'; import { SelectableProvider } from './providers/selectable'; import { Config, Secrets } from './types'; import { generateInferenceEndpointId, getTaskTypeOptions, TaskTypeOption } from './helpers'; @@ -116,13 +116,13 @@ const InferenceAPIConnectorFields: React.FunctionComponent { + (taskType: string, provider?: string) => { // Get task type settings - const currentTaskTypes = await getTaskTypes(http, provider ?? config?.provider); + const currentProvider = providers?.find((p) => p.provider === (provider ?? config?.provider)); + const currentTaskTypes = currentProvider?.task_types; const newTaskType = currentTaskTypes?.find((p) => p.task_type === taskType); setSelectedTaskType(taskType); - generateInferenceEndpointId(config, setFieldValue); // transform the schema const newTaskTypeSchema = Object.keys(newTaskType?.configuration ?? {}).map((k) => ({ @@ -150,19 +150,23 @@ const InferenceAPIConnectorFields: React.FunctionComponent { + (provider?: string) => { const newProvider = providers?.find((p) => p.provider === provider); // Update task types list available for the selected provider - const providerTaskTypes = newProvider?.taskTypes ?? []; + const providerTaskTypes = (newProvider?.task_types ?? []).map((t) => t.task_type); setTaskTypeOptions(getTaskTypeOptions(providerTaskTypes)); if (providerTaskTypes.length > 0) { - await onTaskTypeOptionsSelect(providerTaskTypes[0], provider); + onTaskTypeOptionsSelect(providerTaskTypes[0], provider); } // Update connector providerSchema @@ -203,9 +207,8 @@ const InferenceAPIConnectorFields: React.FunctionComponent { - const getTaskTypeSchema = async () => { - const currentTaskTypes = await getTaskTypes(http, config?.provider ?? ''); - const newTaskType = currentTaskTypes?.find((p) => p.task_type === config?.taskType); + const getTaskTypeSchema = (taskTypes: InferenceTaskType[]) => { + const newTaskType = taskTypes.find((p) => p.task_type === config?.taskType); // transform the schema const newTaskTypeSchema = Object.keys(newTaskType?.configuration ?? {}).map((k) => ({ @@ -228,7 +231,7 @@ const InferenceAPIConnectorFields: React.FunctionComponent + Object.keys(SERVICE_PROVIDERS).includes(config?.provider) + ? SERVICE_PROVIDERS[config?.provider as ServiceProviderKeys].icon + : undefined, + [config?.provider] + ); + + const providerName = useMemo( + () => + Object.keys(SERVICE_PROVIDERS).includes(config?.provider) + ? SERVICE_PROVIDERS[config?.provider as ServiceProviderKeys].name + : config?.provider, + [config?.provider] + ); + const providerSuperSelect = useCallback( (isInvalid: boolean) => ( jest.resetAllMocks()); - -describe.skip('getTaskTypes', () => { - test('should call get inference task types api', async () => { - const apiResponse = { - amazonbedrock: [ - { - task_type: 'completion', - configuration: { - max_new_tokens: { - display: DisplayType.NUMERIC, - label: 'Max new tokens', - order: 1, - required: false, - sensitive: false, - tooltip: 'Sets the maximum number for the output tokens to be generated.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'text_embedding', - configuration: {}, - }, - ], - }; - http.get.mockResolvedValueOnce(apiResponse); - - const result = await getTaskTypes(http, 'amazonbedrock'); - expect(result).toEqual(apiResponse); - }); -}); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/get_task_types.ts b/x-pack/plugins/stack_connectors/public/connector_types/inference/get_task_types.ts deleted file mode 100644 index a4fbbd6a6288b..0000000000000 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/get_task_types.ts +++ /dev/null @@ -1,606 +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 type { HttpSetup } from '@kbn/core-http-browser'; -import { DisplayType, FieldType } from '../lib/dynamic_config/types'; -import { FieldsConfiguration } from './types'; - -export interface InferenceTaskType { - task_type: string; - configuration: FieldsConfiguration; -} - -// this http param is for the future migrating to real API -export const getTaskTypes = (http: HttpSetup, provider: string): Promise => { - const providersTaskTypes: Record = { - openai: [ - { - task_type: 'completion', - configuration: { - user: { - display: DisplayType.TEXTBOX, - label: 'User', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the user issuing the request.', - type: FieldType.STRING, - validations: [], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'text_embedding', - configuration: { - user: { - display: DisplayType.TEXTBOX, - label: 'User', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the user issuing the request.', - type: FieldType.STRING, - validations: [], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - ], - mistral: [ - { - task_type: 'text_embedding', - configuration: {}, - }, - ], - hugging_face: [ - { - task_type: 'text_embedding', - configuration: {}, - }, - ], - googlevertexai: [ - { - task_type: 'text_embedding', - configuration: { - auto_truncate: { - display: DisplayType.TOGGLE, - label: 'Auto truncate', - order: 1, - required: false, - sensitive: false, - tooltip: - 'Specifies if the API truncates inputs longer than the maximum token length automatically.', - type: FieldType.BOOLEAN, - validations: [], - value: false, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'rerank', - configuration: { - top_n: { - display: DisplayType.TOGGLE, - label: 'Top N', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the number of the top n documents, which should be returned.', - type: FieldType.BOOLEAN, - validations: [], - value: false, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - ], - googleaistudio: [ - { - task_type: 'completion', - configuration: {}, - }, - { - task_type: 'text_embedding', - configuration: {}, - }, - ], - elasticsearch: [ - { - task_type: 'rerank', - configuration: { - return_documents: { - display: DisplayType.TOGGLE, - label: 'Return documents', - options: [], - order: 1, - required: false, - sensitive: false, - tooltip: 'Returns the document instead of only the index.', - type: FieldType.BOOLEAN, - validations: [], - value: true, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'sparse_embedding', - configuration: {}, - }, - { - task_type: 'text_embedding', - configuration: {}, - }, - ], - cohere: [ - { - task_type: 'completion', - configuration: {}, - }, - { - task_type: 'text_embedding', - configuration: { - input_type: { - display: DisplayType.DROPDOWN, - label: 'Input type', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the type of input passed to the model.', - type: FieldType.STRING, - validations: [], - options: [ - { - label: 'classification', - value: 'classification', - }, - { - label: 'clusterning', - value: 'clusterning', - }, - { - label: 'ingest', - value: 'ingest', - }, - { - label: 'search', - value: 'search', - }, - ], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - truncate: { - display: DisplayType.DROPDOWN, - options: [ - { - label: 'NONE', - value: 'NONE', - }, - { - label: 'START', - value: 'START', - }, - { - label: 'END', - value: 'END', - }, - ], - label: 'Truncate', - order: 2, - required: false, - sensitive: false, - tooltip: 'Specifies how the API handles inputs longer than the maximum token length.', - type: FieldType.STRING, - validations: [], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'rerank', - configuration: { - return_documents: { - display: DisplayType.TOGGLE, - label: 'Return documents', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specify whether to return doc text within the results.', - type: FieldType.BOOLEAN, - validations: [], - value: false, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - top_n: { - display: DisplayType.NUMERIC, - label: 'Top N', - order: 1, - required: false, - sensitive: false, - tooltip: - 'The number of most relevant documents to return, defaults to the number of the documents.', - type: FieldType.INTEGER, - validations: [], - value: false, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - ], - azureopenai: [ - { - task_type: 'completion', - configuration: { - user: { - display: DisplayType.TEXTBOX, - label: 'User', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the user issuing the request.', - type: FieldType.STRING, - validations: [], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'text_embedding', - configuration: { - user: { - display: DisplayType.TEXTBOX, - label: 'User', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the user issuing the request.', - type: FieldType.STRING, - validations: [], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - ], - azureaistudio: [ - { - task_type: 'completion', - configuration: { - user: { - display: DisplayType.TEXTBOX, - label: 'User', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the user issuing the request.', - type: FieldType.STRING, - validations: [], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'text_embedding', - configuration: { - do_sample: { - display: DisplayType.NUMERIC, - label: 'Do sample', - order: 1, - required: false, - sensitive: false, - tooltip: 'Instructs the inference process to perform sampling or not.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - max_new_tokens: { - display: DisplayType.NUMERIC, - label: 'Max new tokens', - order: 1, - required: false, - sensitive: false, - tooltip: 'Provides a hint for the maximum number of output tokens to be generated.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - temperature: { - display: DisplayType.NUMERIC, - label: 'Temperature', - order: 1, - required: false, - sensitive: false, - tooltip: 'A number in the range of 0.0 to 2.0 that specifies the sampling temperature.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - top_p: { - display: DisplayType.NUMERIC, - label: 'Top P', - order: 1, - required: false, - sensitive: false, - tooltip: - 'A number in the range of 0.0 to 2.0 that is an alternative value to temperature. Should not be used if temperature is specified.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - ], - amazonbedrock: [ - { - task_type: 'completion', - configuration: { - max_new_tokens: { - display: DisplayType.NUMERIC, - label: 'Max new tokens', - order: 1, - required: false, - sensitive: false, - tooltip: 'Sets the maximum number for the output tokens to be generated.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - temperature: { - display: DisplayType.NUMERIC, - label: 'Temperature', - order: 1, - required: false, - sensitive: false, - tooltip: - 'A number between 0.0 and 1.0 that controls the apparent creativity of the results.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - top_p: { - display: DisplayType.NUMERIC, - label: 'Top P', - order: 1, - required: false, - sensitive: false, - tooltip: - 'Alternative to temperature. A number in the range of 0.0 to 1.0, to eliminate low-probability tokens.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - top_k: { - display: DisplayType.NUMERIC, - label: 'Top K', - order: 1, - required: false, - sensitive: false, - tooltip: - 'Only available for anthropic, cohere, and mistral providers. Alternative to temperature.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'text_embedding', - configuration: {}, - }, - ], - anthropic: [ - { - task_type: 'completion', - configuration: { - max_tokens: { - display: DisplayType.NUMERIC, - label: 'Max tokens', - order: 1, - required: true, - sensitive: false, - tooltip: 'The maximum number of tokens to generate before stopping.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - temperature: { - display: DisplayType.TEXTBOX, - label: 'Temperature', - order: 2, - required: false, - sensitive: false, - tooltip: 'The amount of randomness injected into the response.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - top_p: { - display: DisplayType.NUMERIC, - label: 'Top P', - order: 4, - required: false, - sensitive: false, - tooltip: 'Specifies to use Anthropic’s nucleus sampling.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - top_k: { - display: DisplayType.NUMERIC, - label: 'Top K', - order: 3, - required: false, - sensitive: false, - tooltip: 'Specifies to only sample from the top K options for each subsequent token.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - ], - 'alibabacloud-ai-search': [ - { - task_type: 'text_embedding', - configuration: { - input_type: { - display: DisplayType.DROPDOWN, - label: 'Input type', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the type of input passed to the model.', - type: FieldType.STRING, - validations: [], - options: [ - { - label: 'ingest', - value: 'ingest', - }, - { - label: 'search', - value: 'search', - }, - ], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'sparse_embedding', - configuration: { - input_type: { - display: DisplayType.DROPDOWN, - label: 'Input type', - order: 1, - required: false, - sensitive: false, - tooltip: 'Specifies the type of input passed to the model.', - type: FieldType.STRING, - validations: [], - options: [ - { - label: 'ingest', - value: 'ingest', - }, - { - label: 'search', - value: 'search', - }, - ], - value: '', - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - return_token: { - display: DisplayType.TOGGLE, - label: 'Return token', - options: [], - order: 1, - required: false, - sensitive: false, - tooltip: - 'If `true`, the token name will be returned in the response. Defaults to `false` which means only the token ID will be returned in the response.', - type: FieldType.BOOLEAN, - validations: [], - value: true, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - task_type: 'completion', - configuration: {}, - }, - { - task_type: 'rerank', - configuration: {}, - }, - ], - watsonxai: [ - { - task_type: 'text_embedding', - configuration: {}, - }, - ], - }; - return Promise.resolve(providersTaskTypes[provider]); -}; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/helpers.ts b/x-pack/plugins/stack_connectors/public/connector_types/inference/helpers.ts index 0e1e4cdaa41ad..8638caa998eff 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/helpers.ts +++ b/x-pack/plugins/stack_connectors/public/connector_types/inference/helpers.ts @@ -7,7 +7,7 @@ import { isEmpty } from 'lodash/fp'; import { ValidationFunc } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; -import { ConfigEntryView } from '../lib/dynamic_config/types'; +import { ConfigEntryView } from '../../../common/dynamic_config/types'; import { Config } from './types'; import * as i18n from './translations'; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/hidden_fields.tsx b/x-pack/plugins/stack_connectors/public/connector_types/inference/hidden_fields.tsx index 9b28d35aaaf3a..f6df891b4b9c8 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/hidden_fields.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/inference/hidden_fields.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { HiddenField } from '@kbn/es-ui-shared-plugin/static/forms/components'; import { UseField } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; +import { ConfigEntryView } from '../../../common/dynamic_config/types'; import { getNonEmptyValidator } from './helpers'; -import { ConfigEntryView } from '../lib/dynamic_config/types'; export const getProviderSecretsHiddenField = ( providerSchema: ConfigEntryView[], diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/get_providers.ts b/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/get_providers.ts index 109266c1273fc..badc0cb61030d 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/get_providers.ts +++ b/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/get_providers.ts @@ -9,1025 +9,11 @@ import type { HttpSetup } from '@kbn/core-http-browser'; import { i18n } from '@kbn/i18n'; import { useQuery } from '@tanstack/react-query'; import type { ToastsStart } from '@kbn/core-notifications-browser'; -import { DisplayType, FieldType } from '../../lib/dynamic_config/types'; -import { FieldsConfiguration } from '../types'; +import { INTERNAL_BASE_STACK_CONNECTORS_API_PATH } from '../../../../common'; +import { InferenceProvider } from '../../../../common/inference/types'; -export interface InferenceProvider { - provider: string; - taskTypes: string[]; - logo?: string; - configuration: FieldsConfiguration; -} - -export const getProviders = (http: HttpSetup): Promise => { - const providers = [ - { - provider: 'openai', - logo: '', // should be openai logo here, the hardcoded uses assets/images - taskTypes: ['completion', 'text_embedding'], - configuration: { - api_key: { - display: DisplayType.TEXTBOX, - label: 'API Key', - order: 3, - required: true, - sensitive: true, - tooltip: `The OpenAI API authentication key. For more details about generating OpenAI API keys, refer to the https://platform.openai.com/account/api-keys.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - model_id: { - display: DisplayType.TEXTBOX, - label: 'Model ID', - order: 2, - required: true, - sensitive: false, - tooltip: 'The name of the model to use for the inference task.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - organization_id: { - display: DisplayType.TEXTBOX, - label: 'Organization ID', - order: 4, - required: false, - sensitive: false, - tooltip: 'The unique identifier of your organization.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - url: { - display: DisplayType.TEXTBOX, - label: 'URL', - order: 1, - required: true, - sensitive: false, - tooltip: - 'The OpenAI API endpoint URL. For more information on the URL, refer to the https://platform.openai.com/docs/api-reference.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: 'https://api.openai.com/v1/chat/completions', - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 5, - required: false, - sensitive: false, - tooltip: - 'Default number of requests allowed per minute. For text_embedding is 3000. For completion is 500.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'googleaistudio', - logo: '', // should be googleaistudio logo here, the hardcoded uses assets/images - taskTypes: ['completion', 'text_embedding'], - configuration: { - api_key: { - display: DisplayType.TEXTBOX, - label: 'API Key', - order: 1, - required: true, - sensitive: true, - tooltip: `API Key for the provider you're connecting to`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - model_id: { - display: DisplayType.TEXTBOX, - label: 'Model ID', - order: 2, - required: true, - sensitive: false, - tooltip: `ID of the LLM you're using`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 5, - required: false, - sensitive: false, - tooltip: 'Minimize the number of rate limit errors.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'amazonbedrock', - logo: '', // should be amazonbedrock logo here, the hardcoded uses assets/images - taskTypes: ['completion', 'text_embedding'], - configuration: { - access_key: { - display: DisplayType.TEXTBOX, - label: 'Access Key', - order: 1, - required: true, - sensitive: true, - tooltip: `A valid AWS access key that has permissions to use Amazon Bedrock.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - secret_key: { - display: DisplayType.TEXTBOX, - label: 'Secret Key', - order: 2, - required: true, - sensitive: true, - tooltip: `A valid AWS secret key that is paired with the access_key.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - provider: { - display: DisplayType.DROPDOWN, - label: 'Provider', - order: 3, - required: true, - options: [ - { - label: 'amazontitan', - value: 'amazontitan', - }, - { - label: 'anthropic', - value: 'anthropic', - }, - { - label: 'ai21labs', - value: 'ai21labs', - }, - { - label: 'cohere', - value: 'cohere', - }, - { - label: 'meta', - value: 'meta', - }, - { - label: 'mistral', - value: 'mistral', - }, - ], - sensitive: false, - tooltip: 'The model provider for your deployment.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - model: { - display: DisplayType.TEXTBOX, - label: 'Model', - order: 4, - required: true, - sensitive: false, - tooltip: `The base model ID or an ARN to a custom model based on a foundational model.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - region: { - display: DisplayType.TEXTBOX, - label: 'Region', - order: 5, - required: true, - sensitive: false, - tooltip: `The region that your model or ARN is deployed in.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 6, - required: false, - sensitive: false, - tooltip: - 'By default, the amazonbedrock service sets the number of requests allowed per minute to 240.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'googlevertexai', - logo: '', // should be googlevertexai logo here, the hardcoded uses assets/images - taskTypes: ['text_embedding', 'rerank'], - configuration: { - service_account_json: { - display: DisplayType.TEXTBOX, - label: 'Credentials JSON', - order: 1, - required: true, - sensitive: true, - tooltip: `API Key for the provider you're connecting to`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - model_id: { - display: DisplayType.TEXTBOX, - label: 'Model ID', - order: 2, - required: true, - sensitive: false, - tooltip: `ID of the LLM you're using`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - location: { - display: DisplayType.TEXTBOX, - label: 'GCP Region', - order: 2, - required: true, - sensitive: false, - tooltip: `Please provide the GCP region where the Vertex AI API(s) is enabled. For more information, refer to the {geminiVertexAIDocs}.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - project_id: { - display: DisplayType.TEXTBOX, - label: 'GCP Project', - order: 3, - required: true, - sensitive: false, - tooltip: - 'The GCP Project ID which has Vertex AI API(s) enabled. For more information on the URL, refer to the {geminiVertexAIDocs}.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 5, - required: false, - sensitive: false, - tooltip: 'Minimize the number of rate limit errors.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'mistral', - logo: '', // should be misral logo here, the hardcoded uses assets/images - taskTypes: ['text_embedding'], - configuration: { - api_key: { - display: DisplayType.TEXTBOX, - label: 'API Key', - order: 1, - required: true, - sensitive: true, - tooltip: `API Key for the provider you're connecting to`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - model: { - display: DisplayType.TEXTBOX, - label: 'Model', - order: 2, - required: true, - sensitive: false, - tooltip: `Refer to the Mistral models documentation for the list of available text embedding models`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 4, - required: false, - sensitive: false, - tooltip: 'Minimize the number of rate limit errors.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: 240, - depends_on: [], - }, - max_input_tokens: { - display: DisplayType.NUMERIC, - label: 'Maximum input tokens', - order: 3, - required: false, - sensitive: false, - tooltip: 'Allows you to specify the maximum number of tokens per input.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'hugging_face', - logo: '', // should be hugging_face logo here, the hardcoded uses assets/images - taskTypes: ['text_embedding'], - configuration: { - api_key: { - display: DisplayType.TEXTBOX, - label: 'API Key', - order: 2, - required: true, - sensitive: true, - tooltip: `API Key for the provider you're connecting to`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - url: { - display: DisplayType.TEXTBOX, - label: 'URL', - order: 1, - required: true, - sensitive: false, - tooltip: 'The URL endpoint to use for the requests.', - type: FieldType.STRING, - validations: [], - value: 'https://api.openai.com/v1/embeddings', - ui_restrictions: [], - default_value: 'https://api.openai.com/v1/embeddings', - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 3, - required: false, - sensitive: false, - tooltip: 'Minimize the number of rate limit errors.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'elasticsearch', - logo: '', // elasticsearch logo here - taskTypes: ['sparse_embedding', 'text_embedding', 'rerank'], - configuration: { - model_id: { - display: DisplayType.DROPDOWN, - label: 'Model ID', - order: 1, - required: true, - sensitive: false, - tooltip: `The name of the model to use for the inference task.`, - type: FieldType.STRING, - validations: [], - options: [ - { - label: '.elser_model_1', - value: '.elser_model_1', - }, - { - label: '.elser_model_2', - value: '.elser_model_2', - }, - { - label: '.elser_model_2_linux-x86_64', - value: '.elser_model_2_linux-x86_64', - }, - { - label: '.multilingual-e5-small', - value: '.multilingual-e5-small', - }, - { - label: '.multilingual-e5-small_linux-x86_64', - value: '.multilingual-e5-small_linux-x86_64', - }, - ], - value: null, - ui_restrictions: [], - default_value: '.multilingual-e5-small', - depends_on: [], - }, - num_allocations: { - display: DisplayType.NUMERIC, - label: 'Number allocations', - order: 2, - required: true, - sensitive: false, - tooltip: - 'The total number of allocations this model is assigned across machine learning nodes.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: 1, - depends_on: [], - }, - num_threads: { - display: DisplayType.NUMERIC, - label: 'Number threads', - order: 3, - required: true, - sensitive: false, - tooltip: 'Sets the number of threads used by each model allocation during inference.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: 2, - depends_on: [], - }, - }, - }, - { - provider: 'cohere', - logo: '', // should be cohere logo here, the hardcoded uses assets/images - taskTypes: ['completion', 'text_embedding', 'rerank'], - configuration: { - api_key: { - display: DisplayType.TEXTBOX, - label: 'API Key', - order: 1, - required: true, - sensitive: true, - tooltip: `API Key for the provider you're connecting to`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 5, - required: false, - sensitive: false, - tooltip: 'Minimize the number of rate limit errors.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'azureopenai', - logo: '', // should be azureopenai logo here, the hardcoded uses assets/images - taskTypes: ['completion', 'text_embedding'], - configuration: { - api_key: { - display: DisplayType.TEXTBOX, - label: 'API Key', - order: 1, - required: false, - sensitive: true, - tooltip: `You must provide either an API key or an Entra ID.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - entra_id: { - display: DisplayType.TEXTBOX, - label: 'Entra ID', - order: 2, - required: false, - sensitive: true, - tooltip: `You must provide either an API key or an Entra ID.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - resource_name: { - display: DisplayType.TEXTBOX, - label: 'Resource Name', - order: 3, - required: true, - sensitive: false, - tooltip: `The name of your Azure OpenAI resource`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - api_version: { - display: DisplayType.TEXTBOX, - label: 'API version', - order: 4, - required: true, - sensitive: false, - tooltip: 'The Azure API version ID to use.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - deployment_id: { - display: DisplayType.TEXTBOX, - label: 'Deployment ID', - order: 5, - required: true, - sensitive: false, - tooltip: 'The deployment name of your deployed models.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 5, - required: false, - sensitive: false, - tooltip: - 'The azureopenai service sets a default number of requests allowed per minute depending on the task type.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'azureaistudio', - logo: '', // should be azureaistudio logo here, the hardcoded uses assets/images - taskTypes: ['completion', 'text_embedding'], - configuration: { - api_key: { - display: DisplayType.TEXTBOX, - label: 'API Key', - order: 1, - required: true, - sensitive: true, - tooltip: `API Key for the provider you're connecting to`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - target: { - display: DisplayType.TEXTBOX, - label: 'Target', - order: 2, - required: true, - sensitive: false, - tooltip: `The target URL of your Azure AI Studio model deployment.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - endpoint_type: { - display: DisplayType.DROPDOWN, - label: 'Endpoint type', - order: 3, - required: true, - sensitive: false, - tooltip: 'Specifies the type of endpoint that is used in your model deployment.', - type: FieldType.STRING, - options: [ - { - label: 'token', - value: 'token', - }, - { - label: 'realtime', - value: 'realtime', - }, - ], - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - provider: { - display: DisplayType.DROPDOWN, - label: 'Provider', - order: 3, - required: true, - options: [ - { - label: 'cohere', - value: 'cohere', - }, - { - label: 'meta', - value: 'meta', - }, - { - label: 'microsoft_phi', - value: 'microsoft_phi', - }, - { - label: 'mistral', - value: 'mistral', - }, - { - label: 'openai', - value: 'openai', - }, - { - label: 'databricks', - value: 'databricks', - }, - ], - sensitive: false, - tooltip: 'The model provider for your deployment.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 5, - required: false, - sensitive: false, - tooltip: 'Minimize the number of rate limit errors.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'anthropic', - logo: '', // should be anthropic logo here, the hardcoded uses assets/images - taskTypes: ['completion'], - configuration: { - api_key: { - display: DisplayType.TEXTBOX, - label: 'API Key', - order: 1, - required: true, - sensitive: true, - tooltip: `API Key for the provider you're connecting to`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - model_id: { - display: DisplayType.TEXTBOX, - label: 'Model ID', - order: 2, - required: true, - sensitive: false, - tooltip: `The name of the model to use for the inference task.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 5, - required: false, - sensitive: false, - tooltip: - 'By default, the anthropic service sets the number of requests allowed per minute to 50.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'watsonxai', - logo: '', // should be anthropic logo here, the hardcoded uses assets/images - taskTypes: ['text_embedding'], - configuration: { - api_version: { - display: DisplayType.TEXTBOX, - label: 'API version', - order: 1, - required: true, - sensitive: false, - tooltip: 'The IBM Watsonx API version ID to use.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - project_id: { - display: DisplayType.TEXTBOX, - label: 'Project ID', - order: 2, - required: true, - sensitive: false, - tooltip: '', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - model_id: { - display: DisplayType.TEXTBOX, - label: 'Model ID', - order: 3, - required: true, - sensitive: false, - tooltip: `The name of the model to use for the inference task.`, - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - url: { - display: DisplayType.TEXTBOX, - label: 'URL', - order: 4, - required: true, - sensitive: false, - tooltip: '', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - max_input_tokens: { - display: DisplayType.NUMERIC, - label: 'Maximum input tokens', - order: 5, - required: false, - sensitive: false, - tooltip: 'Allows you to specify the maximum number of tokens per input.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - { - provider: 'alibabacloud-ai-search', - logo: '', // should be anthropic logo here, the hardcoded uses assets/images - taskTypes: ['completion', 'sparse_embedding', 'text_embedding', 'rerank'], - configuration: { - api_key: { - display: DisplayType.TEXTBOX, - label: 'API Key', - order: 1, - required: true, - sensitive: true, - tooltip: 'A valid API key for the AlibabaCloud AI Search API.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - service_id: { - display: DisplayType.DROPDOWN, - label: 'Project ID', - order: 2, - required: true, - sensitive: false, - tooltip: 'The name of the model service to use for the {infer} task.', - type: FieldType.STRING, - options: [ - { - label: 'ops-text-embedding-001', - value: 'ops-text-embedding-001', - }, - { - label: 'ops-text-embedding-zh-001', - value: 'ops-text-embedding-zh-001', - }, - { - label: 'ops-text-embedding-en-001', - value: 'ops-text-embedding-en-001', - }, - { - label: 'ops-text-embedding-002', - value: 'ops-text-embedding-002', - }, - { - label: 'ops-text-sparse-embedding-001', - value: 'ops-text-sparse-embedding-001', - }, - { - label: 'ops-bge-reranker-larger', - value: 'ops-bge-reranker-larger', - }, - ], - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - host: { - display: DisplayType.TEXTBOX, - label: 'Host', - order: 3, - required: true, - sensitive: false, - tooltip: - 'The name of the host address used for the {infer} task. You can find the host address at https://opensearch.console.aliyun.com/cn-shanghai/rag/api-key[ the API keys section] of the documentation.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - http_schema: { - display: DisplayType.DROPDOWN, - label: 'HTTP Schema', - order: 4, - required: true, - sensitive: false, - tooltip: '', - type: FieldType.STRING, - options: [ - { - label: 'https', - value: 'https', - }, - { - label: 'http', - value: 'http', - }, - ], - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - workspace: { - display: DisplayType.TEXTBOX, - label: 'Workspace', - order: 5, - required: true, - sensitive: false, - tooltip: 'The name of the workspace used for the {infer} task.', - type: FieldType.STRING, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - 'rate_limit.requests_per_minute': { - display: DisplayType.NUMERIC, - label: 'Rate limit', - order: 6, - required: false, - sensitive: false, - tooltip: 'Minimize the number of rate limit errors.', - type: FieldType.INTEGER, - validations: [], - value: null, - ui_restrictions: [], - default_value: null, - depends_on: [], - }, - }, - }, - ] as InferenceProvider[]; - return Promise.resolve( - providers.sort((a, b) => (a.provider > b.provider ? 1 : b.provider > a.provider ? -1 : 0)) - ); +export const getProviders = async (http: HttpSetup): Promise => { + return await http.get(`${INTERNAL_BASE_STACK_CONNECTORS_API_PATH}/_inference/_services`); }; export const useProviders = (http: HttpSetup, toasts: ToastsStart) => { diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/render_service_provider/service_provider.tsx b/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/render_service_provider/service_provider.tsx index 5d2c99ffd92ce..5eb8518a5ea15 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/render_service_provider/service_provider.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/render_service_provider/service_provider.tsx @@ -26,7 +26,7 @@ interface ServiceProviderProps { searchValue?: string; } -type ProviderSolution = 'Observability' | 'Security' | 'Search'; +export type ProviderSolution = 'Observability' | 'Security' | 'Search'; interface ServiceProviderRecord { icon: string; @@ -107,9 +107,7 @@ export const ServiceProviderIcon: React.FC = ({ providerKe return provider ? ( - ) : ( - {providerKey} - ); + ) : null; }; export const ServiceProviderName: React.FC = ({ diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/selectable/index.tsx b/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/selectable/index.tsx index d4527e9c7b9a4..fc31c9dd6c4f7 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/selectable/index.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/inference/providers/selectable/index.tsx @@ -11,6 +11,7 @@ import React, { memo, useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { ServiceProviderKeys } from '../../../../../common/inference/constants'; import { + ProviderSolution, SERVICE_PROVIDERS, ServiceProviderIcon, ServiceProviderName, @@ -47,7 +48,20 @@ const SelectableProviderComponent: React.FC = ({ const renderProviderOption = useCallback>( (option, searchValue) => { - const provider = SERVICE_PROVIDERS[option.label as ServiceProviderKeys]; + const provider = Object.keys(SERVICE_PROVIDERS).includes(option.label) + ? SERVICE_PROVIDERS[option.label as ServiceProviderKeys] + : undefined; + + const supportedBySolutions = (provider && + provider.solutions.map((solution) => ( + + {solution} + + ))) ?? ( + + {'Search' as ProviderSolution} + + ); return ( @@ -65,12 +79,7 @@ const SelectableProviderComponent: React.FC = ({ - {provider && - provider.solutions.map((solution) => ( - - {solution} - - ))} + {supportedBySolutions} diff --git a/x-pack/plugins/stack_connectors/public/connector_types/inference/types.ts b/x-pack/plugins/stack_connectors/public/connector_types/inference/types.ts index 150292894b643..1bd55793bc463 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/inference/types.ts +++ b/x-pack/plugins/stack_connectors/public/connector_types/inference/types.ts @@ -14,7 +14,6 @@ import { SparseEmbeddingParams, TextEmbeddingParams, } from '../../../common/inference/types'; -import { ConfigProperties } from '../lib/dynamic_config/types'; export type InferenceActionParams = | { subAction: SUB_ACTION.COMPLETION; subActionParams: ChatCompleteParams } @@ -22,8 +21,6 @@ export type InferenceActionParams = | { subAction: SUB_ACTION.SPARSE_EMBEDDING; subActionParams: SparseEmbeddingParams } | { subAction: SUB_ACTION.TEXT_EMBEDDING; subActionParams: TextEmbeddingParams }; -export type FieldsConfiguration = Record; - export interface Config { taskType: string; taskTypeConfig?: Record; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_field.tsx b/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_field.tsx index 79ae552a9528a..5560c831c4a61 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_field.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_field.tsx @@ -25,12 +25,12 @@ import { } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; +import { ConfigEntryView, DisplayType } from '../../../../common/dynamic_config/types'; import { ensureBooleanType, ensureCorrectTyping, ensureStringType, } from './connector_configuration_utils'; -import { ConfigEntryView, DisplayType } from './types'; interface ConnectorConfigurationFieldProps { configEntry: ConfigEntryView; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_form_items.tsx b/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_form_items.tsx index 3190ac80275f1..a7063d81719a8 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_form_items.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_form_items.tsx @@ -18,7 +18,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { ConfigEntryView, DisplayType } from './types'; +import { ConfigEntryView, DisplayType } from '../../../../common/dynamic_config/types'; import { ConnectorConfigurationField } from './connector_configuration_field'; interface ConnectorConfigurationFormItemsProps { diff --git a/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_utils.ts b/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_utils.ts index 182327a180a63..cce5bc15fa56c 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_utils.ts +++ b/x-pack/plugins/stack_connectors/public/connector_types/lib/dynamic_config/connector_configuration_utils.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ConfigProperties, FieldType } from './types'; +import { ConfigProperties, FieldType } from '../../../../common/dynamic_config/types'; export type ConnectorConfigEntry = ConfigProperties & { key: string }; diff --git a/x-pack/plugins/stack_connectors/server/plugin.ts b/x-pack/plugins/stack_connectors/server/plugin.ts index aee84d963043d..b20892938735b 100644 --- a/x-pack/plugins/stack_connectors/server/plugin.ts +++ b/x-pack/plugins/stack_connectors/server/plugin.ts @@ -8,7 +8,11 @@ import { PluginInitializerContext, Plugin, CoreSetup, Logger } from '@kbn/core/server'; import { PluginSetupContract as ActionsPluginSetupContract } from '@kbn/actions-plugin/server'; import { registerConnectorTypes } from './connector_types'; -import { validSlackApiChannelsRoute, getWellKnownEmailServiceRoute } from './routes'; +import { + validSlackApiChannelsRoute, + getWellKnownEmailServiceRoute, + getInferenceServicesRoute, +} from './routes'; import { ExperimentalFeatures, parseExperimentalConfigValue, @@ -39,6 +43,7 @@ export class StackConnectorsPlugin implements Plugin { getWellKnownEmailServiceRoute(router); validSlackApiChannelsRoute(router, actions.getActionsConfigurationUtilities(), this.logger); + getInferenceServicesRoute(router); registerConnectorTypes({ actions, diff --git a/x-pack/plugins/stack_connectors/server/routes/get_inference_services.test.ts b/x-pack/plugins/stack_connectors/server/routes/get_inference_services.test.ts new file mode 100644 index 0000000000000..50596028d80a8 --- /dev/null +++ b/x-pack/plugins/stack_connectors/server/routes/get_inference_services.test.ts @@ -0,0 +1,133 @@ +/* + * Copyright 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 { httpServiceMock, httpServerMock } from '@kbn/core/server/mocks'; +import { coreMock } from '@kbn/core/server/mocks'; +import { getInferenceServicesRoute } from './get_inference_services'; +import { DisplayType, FieldType } from '../../common/dynamic_config/types'; + +describe('getInferenceServicesRoute', () => { + it('returns available service providers', async () => { + const router = httpServiceMock.createRouter(); + const core = coreMock.createRequestHandlerContext(); + + const mockResult = [ + { + provider: 'openai', + task_types: [ + { + task_type: 'completion', + configuration: { + user: { + display: DisplayType.TEXTBOX, + label: 'User', + order: 1, + required: false, + sensitive: false, + tooltip: 'Specifies the user issuing the request.', + type: FieldType.STRING, + validations: [], + value: '', + ui_restrictions: [], + default_value: null, + depends_on: [], + }, + }, + }, + ], + configuration: { + api_key: { + display: DisplayType.TEXTBOX, + label: 'API Key', + order: 3, + required: true, + sensitive: true, + tooltip: `The OpenAI API authentication key. For more details about generating OpenAI API keys, refer to the https://platform.openai.com/account/api-keys.`, + type: FieldType.STRING, + validations: [], + value: null, + ui_restrictions: [], + default_value: null, + depends_on: [], + }, + model_id: { + display: DisplayType.TEXTBOX, + label: 'Model ID', + order: 2, + required: true, + sensitive: false, + tooltip: 'The name of the model to use for the inference task.', + type: FieldType.STRING, + validations: [], + value: null, + ui_restrictions: [], + default_value: null, + depends_on: [], + }, + organization_id: { + display: DisplayType.TEXTBOX, + label: 'Organization ID', + order: 4, + required: false, + sensitive: false, + tooltip: 'The unique identifier of your organization.', + type: FieldType.STRING, + validations: [], + value: null, + ui_restrictions: [], + default_value: null, + depends_on: [], + }, + url: { + display: DisplayType.TEXTBOX, + label: 'URL', + order: 1, + required: true, + sensitive: false, + tooltip: + 'The OpenAI API endpoint URL. For more information on the URL, refer to the https://platform.openai.com/docs/api-reference.', + type: FieldType.STRING, + validations: [], + value: null, + ui_restrictions: [], + default_value: 'https://api.openai.com/v1/chat/completions', + depends_on: [], + }, + 'rate_limit.requests_per_minute': { + display: DisplayType.NUMERIC, + label: 'Rate limit', + order: 5, + required: false, + sensitive: false, + tooltip: + 'Default number of requests allowed per minute. For text_embedding is 3000. For completion is 500.', + type: FieldType.INTEGER, + validations: [], + value: null, + ui_restrictions: [], + default_value: null, + depends_on: [], + }, + }, + }, + ]; + core.elasticsearch.client.asInternalUser.transport.request.mockResolvedValue(mockResult); + + getInferenceServicesRoute(router); + + const [config, handler] = router.get.mock.calls[0]; + expect(config.path).toMatchInlineSnapshot(`"/internal/stack_connectors/_inference/_services"`); + + const mockResponse = httpServerMock.createResponseFactory(); + const mockRequest = httpServerMock.createKibanaRequest(); + await handler({ core }, mockRequest, mockResponse); + + expect(mockResponse.ok).toHaveBeenCalledWith({ + body: mockResult, + }); + }); +}); diff --git a/x-pack/plugins/stack_connectors/server/routes/get_inference_services.ts b/x-pack/plugins/stack_connectors/server/routes/get_inference_services.ts new file mode 100644 index 0000000000000..1396072834261 --- /dev/null +++ b/x-pack/plugins/stack_connectors/server/routes/get_inference_services.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from '@kbn/core/server'; +import { InferenceProvider } from '../../common/inference/types'; +import { INTERNAL_BASE_STACK_CONNECTORS_API_PATH } from '../../common'; + +export const getInferenceServicesRoute = (router: IRouter) => { + router.get( + { + path: `${INTERNAL_BASE_STACK_CONNECTORS_API_PATH}/_inference/_services`, + options: { + access: 'internal', + }, + validate: false, + }, + handler + ); + + async function handler( + ctx: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise { + const esClient = (await ctx.core).elasticsearch.client.asInternalUser; + + const response = await esClient.transport.request<{ + endpoints: InferenceProvider[]; + }>({ + method: 'GET', + path: `/_inference/_services`, + }); + + return res.ok({ + body: response, + }); + } +}; diff --git a/x-pack/plugins/stack_connectors/server/routes/index.ts b/x-pack/plugins/stack_connectors/server/routes/index.ts index cd9857b2168ed..e64995e1a50ef 100644 --- a/x-pack/plugins/stack_connectors/server/routes/index.ts +++ b/x-pack/plugins/stack_connectors/server/routes/index.ts @@ -7,3 +7,4 @@ export { getWellKnownEmailServiceRoute } from './get_well_known_email_service'; export { validSlackApiChannelsRoute } from './valid_slack_api_channels'; +export { getInferenceServicesRoute } from './get_inference_services'; From 6e5f793c489e23e41d372f18cc22ab363b9724f4 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:26:12 +1100 Subject: [PATCH 002/105] [api-docs] 2024-11-12 Daily api_docs build (#199729) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/889 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- .../ai_assistant_management_selection.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/apm_data_access.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_data_migration.mdx | 2 +- api_docs/cloud_defend.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_quality.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_usage.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/dataset_quality.mdx | 2 +- api_docs/deprecations_by_api.mdx | 3 +- api_docs/deprecations_by_plugin.mdx | 3 +- 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/discover_shared.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/elastic_assistant.devdocs.json | 21 + api_docs/elastic_assistant.mdx | 4 +- 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/entities_data_access.mdx | 2 +- api_docs/entity_manager.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/esql.mdx | 2 +- api_docs/esql_data_grid.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_annotation_listing.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/fields_metadata.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 +- .../index_lifecycle_management.devdocs.json | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/inference.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/ingest_pipelines.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/integration_assistant.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/inventory.mdx | 2 +- api_docs/investigate.mdx | 2 +- api_docs/investigate_app.mdx | 2 +- api_docs/kbn_actions_types.mdx | 2 +- api_docs/kbn_ai_assistant.mdx | 2 +- api_docs/kbn_ai_assistant_common.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_log_pattern_analysis.mdx | 2 +- api_docs/kbn_aiops_log_rate_analysis.mdx | 2 +- .../kbn_alerting_api_integration_helpers.mdx | 2 +- api_docs/kbn_alerting_comparators.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerting_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_grouping.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_collection_utils.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_data_view.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_types.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_avc_banner.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_bfetch_error.mdx | 2 +- api_docs/kbn_calculate_auto.mdx | 2 +- .../kbn_calculate_width_from_char_count.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cbor.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_cloud_security_posture.mdx | 2 +- .../kbn_cloud_security_posture_common.mdx | 2 +- api_docs/kbn_cloud_security_posture_graph.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mock.mdx | 2 +- api_docs/kbn_code_owners.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 +- ...ent_management_content_insights_public.mdx | 2 +- ...ent_management_content_insights_server.mdx | 2 +- ...bn_content_management_favorites_public.mdx | 2 +- ...bn_content_management_favorites_server.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...tent_management_table_list_view_common.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- .../kbn_content_management_user_profiles.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- .../kbn_core_analytics_browser.devdocs.json | 168 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- .../kbn_core_analytics_server.devdocs.json | 168 +- 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.devdocs.json | 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_feature_flags_browser.mdx | 2 +- ...bn_core_feature_flags_browser_internal.mdx | 2 +- .../kbn_core_feature_flags_browser_mocks.mdx | 2 +- api_docs/kbn_core_feature_flags_server.mdx | 2 +- ...kbn_core_feature_flags_server_internal.mdx | 2 +- .../kbn_core_feature_flags_server_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 | 8 + 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 +- .../kbn_core_plugins_contracts_browser.mdx | 2 +- .../kbn_core_plugins_contracts_server.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 +- .../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 +- 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_security_browser.mdx | 2 +- .../kbn_core_security_browser_internal.mdx | 2 +- api_docs/kbn_core_security_browser_mocks.mdx | 2 +- api_docs/kbn_core_security_common.mdx | 2 +- api_docs/kbn_core_security_server.mdx | 2 +- .../kbn_core_security_server_internal.mdx | 2 +- api_docs/kbn_core_security_server_mocks.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 +- .../kbn_core_test_helpers_model_versions.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_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_profile_browser.mdx | 2 +- ...kbn_core_user_profile_browser_internal.mdx | 2 +- .../kbn_core_user_profile_browser_mocks.mdx | 2 +- api_docs/kbn_core_user_profile_common.mdx | 2 +- api_docs/kbn_core_user_profile_server.mdx | 2 +- .../kbn_core_user_profile_server_internal.mdx | 2 +- .../kbn_core_user_profile_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.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_custom_icons.mdx | 2 +- api_docs/kbn_custom_integrations.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_forge.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_data_stream_adapter.mdx | 2 +- api_docs/kbn_data_view_utils.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_fleet.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.devdocs.json | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_deeplinks_security.mdx | 2 +- api_docs/kbn_deeplinks_shared.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 +- ...iscover_contextual_components.devdocs.json | 4 +- .../kbn_discover_contextual_components.mdx | 2 +- api_docs/kbn_discover_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_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_agent_utils.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_elastic_assistant_common.mdx | 2 +- api_docs/kbn_entities_schema.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.devdocs.json | 4 + api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_esql_ast.mdx | 2 +- api_docs/kbn_esql_editor.mdx | 2 +- api_docs/kbn_esql_utils.mdx | 2 +- api_docs/kbn_esql_validation_autocomplete.mdx | 2 +- api_docs/kbn_event_annotation_common.mdx | 2 +- api_docs/kbn_event_annotation_components.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_field_utils.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- api_docs/kbn_formatters.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- .../kbn_ftr_common_functional_ui_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_grid_layout.mdx | 2 +- api_docs/kbn_grouping.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 +- ...ycle_management_common_shared.devdocs.json | 1447 +++++++++++++++++ ...dex_lifecycle_management_common_shared.mdx | 33 + .../kbn_index_management_shared_types.mdx | 2 +- api_docs/kbn_inference_common.mdx | 2 +- api_docs/kbn_inference_integration_flyout.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_investigation_shared.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_ipynb.mdx | 2 +- api_docs/kbn_item_buffer.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_json_schemas.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- api_docs/kbn_language_documentation.mdx | 2 +- api_docs/kbn_lens_embeddable_utils.mdx | 2 +- api_docs/kbn_lens_formula_docs.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_content_badge.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- .../kbn_management_settings_application.mdx | 2 +- ...ent_settings_components_field_category.mdx | 2 +- ...gement_settings_components_field_input.mdx | 2 +- ...nagement_settings_components_field_row.mdx | 2 +- ...bn_management_settings_components_form.mdx | 2 +- ...n_management_settings_field_definition.mdx | 2 +- .../kbn_management_settings_ids.devdocs.json | 15 - api_docs/kbn_management_settings_ids.mdx | 4 +- ...n_management_settings_section_registry.mdx | 2 +- api_docs/kbn_management_settings_types.mdx | 2 +- .../kbn_management_settings_utilities.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_manifest.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 +- api_docs/kbn_ml_cancellable_search.mdx | 2 +- api_docs/kbn_ml_category_validator.mdx | 2 +- api_docs/kbn_ml_chi2test.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_field_stats_flyout.mdx | 2 +- api_docs/kbn_ml_in_memory_table.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_parse_interval.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_time_buckets.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_ui_actions.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_ml_validators.mdx | 2 +- api_docs/kbn_mock_idp_utils.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_object_versioning_utils.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- .../kbn_observability_alerting_rule_utils.mdx | 2 +- .../kbn_observability_alerting_test_data.mdx | 2 +- ...ility_get_padded_alert_time_range_util.mdx | 2 +- api_docs/kbn_observability_logs_overview.mdx | 2 +- ...kbn_observability_synthetics_test_data.mdx | 2 +- api_docs/kbn_openapi_bundler.mdx | 2 +- api_docs/kbn_openapi_generator.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 +- api_docs/kbn_panel_loader.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_check.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_presentation_containers.mdx | 2 +- api_docs/kbn_presentation_publishing.mdx | 2 +- api_docs/kbn_product_doc_artifact_builder.mdx | 2 +- api_docs/kbn_profiling_utils.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_react_hooks.mdx | 2 +- api_docs/kbn_react_kibana_context_common.mdx | 2 +- api_docs/kbn_react_kibana_context_render.mdx | 2 +- api_docs/kbn_react_kibana_context_root.mdx | 2 +- api_docs/kbn_react_kibana_context_styled.mdx | 2 +- api_docs/kbn_react_kibana_context_theme.mdx | 2 +- api_docs/kbn_react_kibana_mount.mdx | 2 +- api_docs/kbn_recently_accessed.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_reporting_csv_share_panel.mdx | 2 +- api_docs/kbn_reporting_export_types_csv.mdx | 2 +- .../kbn_reporting_export_types_csv_common.mdx | 2 +- api_docs/kbn_reporting_export_types_pdf.mdx | 2 +- .../kbn_reporting_export_types_pdf_common.mdx | 2 +- api_docs/kbn_reporting_export_types_png.mdx | 2 +- .../kbn_reporting_export_types_png_common.mdx | 2 +- api_docs/kbn_reporting_mocks_server.mdx | 2 +- api_docs/kbn_reporting_public.mdx | 2 +- api_docs/kbn_reporting_server.mdx | 2 +- api_docs/kbn_resizable_layout.mdx | 2 +- .../kbn_response_ops_feature_flag_service.mdx | 2 +- api_docs/kbn_response_ops_rule_params.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rollup.mdx | 2 +- api_docs/kbn_router_to_openapispec.mdx | 2 +- api_docs/kbn_router_utils.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_screenshotting_server.mdx | 2 +- api_docs/kbn_search_api_keys_components.mdx | 2 +- api_docs/kbn_search_api_keys_server.mdx | 2 +- api_docs/kbn_search_api_panels.mdx | 2 +- api_docs/kbn_search_connectors.mdx | 2 +- api_docs/kbn_search_errors.mdx | 2 +- api_docs/kbn_search_index_documents.mdx | 2 +- api_docs/kbn_search_response_warnings.mdx | 2 +- api_docs/kbn_search_shared_ui.mdx | 2 +- api_docs/kbn_search_types.mdx | 2 +- api_docs/kbn_security_api_key_management.mdx | 2 +- api_docs/kbn_security_authorization_core.mdx | 2 +- ...kbn_security_authorization_core_common.mdx | 2 +- api_docs/kbn_security_form_components.mdx | 2 +- api_docs/kbn_security_hardening.mdx | 2 +- api_docs/kbn_security_plugin_types_common.mdx | 2 +- api_docs/kbn_security_plugin_types_public.mdx | 2 +- api_docs/kbn_security_plugin_types_server.mdx | 2 +- .../kbn_security_role_management_model.mdx | 2 +- ...kbn_security_solution_distribution_bar.mdx | 2 +- api_docs/kbn_security_solution_features.mdx | 2 +- api_docs/kbn_security_solution_navigation.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- api_docs/kbn_security_ui_components.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_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 +- .../kbn_server_route_repository_client.mdx | 2 +- .../kbn_server_route_repository_utils.mdx | 2 +- api_docs/kbn_serverless_common_settings.mdx | 2 +- .../kbn_serverless_observability_settings.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_search_settings.mdx | 2 +- api_docs/kbn_serverless_security_settings.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 +- .../kbn_shared_ux_button_exit_full_screen.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_error_boundary.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_tabbed_modal.mdx | 2 +- api_docs/kbn_shared_ux_table_persist.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_sort_predicates.mdx | 2 +- api_docs/kbn_sse_utils.mdx | 2 +- api_docs/kbn_sse_utils_client.mdx | 2 +- api_docs/kbn_sse_utils_server.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_synthetics_e2e.mdx | 2 +- api_docs/kbn_synthetics_private_location.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_eui_helpers.mdx | 2 +- api_docs/kbn_test_jest_helpers.devdocs.json | 4 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_timerange.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_transpose_utils.mdx | 2 +- api_docs/kbn_triggers_actions_ui_types.mdx | 2 +- api_docs/kbn_try_in_console.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_data_table.mdx | 2 +- api_docs/kbn_unified_doc_viewer.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_unsaved_changes_badge.mdx | 2 +- api_docs/kbn_unsaved_changes_prompt.mdx | 2 +- api_docs/kbn_use_tracked_promise.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_visualization_ui_components.mdx | 2 +- api_docs/kbn_visualization_utils.mdx | 2 +- api_docs/kbn_xstate_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kbn_zod.mdx | 2 +- api_docs/kbn_zod_helpers.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/links.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/logs_data_access.mdx | 2 +- api_docs/logs_explorer.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/metrics_data_access.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/mock_idp_plugin.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/no_data_page.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.devdocs.json | 8 +- api_docs/observability.mdx | 2 +- api_docs/observability_a_i_assistant.mdx | 2 +- api_docs/observability_a_i_assistant_app.mdx | 2 +- .../observability_ai_assistant_management.mdx | 2 +- api_docs/observability_logs_explorer.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/painless_lab.mdx | 2 +- api_docs/plugin_directory.mdx | 15 +- api_docs/presentation_panel.mdx | 2 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/profiling_data_access.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.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/search_assistant.mdx | 2 +- api_docs/search_connectors.mdx | 2 +- api_docs/search_homepage.mdx | 2 +- api_docs/search_indices.devdocs.json | 2 +- api_docs/search_indices.mdx | 2 +- api_docs/search_inference_endpoints.mdx | 2 +- api_docs/search_notebooks.mdx | 2 +- api_docs/search_playground.devdocs.json | 15 +- api_docs/search_playground.mdx | 7 +- 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/slo.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_management_section.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_doc_viewer.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/uptime.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/visualizations.devdocs.json | 14 - api_docs/visualizations.mdx | 4 +- 774 files changed, 2356 insertions(+), 1101 deletions(-) create mode 100644 api_docs/kbn_index_lifecycle_management_common_shared.devdocs.json create mode 100644 api_docs/kbn_index_lifecycle_management_common_shared.mdx diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index b8e1e2f95140f..8213690c68bbc 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: 2024-11-10 +date: 2024-11-12 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 00759b204646d..6ff23feb1abea 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index 55226b95b7e39..903d7bb8564d7 100644 --- a/api_docs/ai_assistant_management_selection.mdx +++ b/api_docs/ai_assistant_management_selection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementSelection title: "aiAssistantManagementSelection" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementSelection plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementSelection'] --- import aiAssistantManagementSelectionObj from './ai_assistant_management_selection.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 51ff2b2177fb5..2dbb911712afe 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: 2024-11-10 +date: 2024-11-12 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 a226470d4e6c3..f1c95bf42eee4 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: 2024-11-10 +date: 2024-11-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 bda18816dc5a7..d0518c5574ce6 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/apm_data_access.mdx b/api_docs/apm_data_access.mdx index 1567922bf310f..76949f4388791 100644 --- a/api_docs/apm_data_access.mdx +++ b/api_docs/apm_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apmDataAccess title: "apmDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the apmDataAccess plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index e8d4cbfc2e8de..4c8900cf3582a 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: 2024-11-10 +date: 2024-11-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 97275e9fa2082..a9e8cc610f7b8 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: 2024-11-10 +date: 2024-11-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 4abcc9b29d104..477390c3afae8 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: 2024-11-10 +date: 2024-11-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 18f0eec76147b..dd96643533e4d 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: 2024-11-10 +date: 2024-11-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 b244870c6ed5a..52e0f0e1b1e73 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: 2024-11-10 +date: 2024-11-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 981162c665fee..05c7d8e004883 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 96a185b5ecdac..edb6f7038849f 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: 2024-11-10 +date: 2024-11-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 dcf04fa9d5218..3d811c99930f9 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 6054ff7c3b449..eb53334573259 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: 2024-11-10 +date: 2024-11-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 0910343b0ba55..0d6bbaaeed5ff 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: 2024-11-10 +date: 2024-11-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 3d2e18a61a112..458f4f5f71079 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: 2024-11-10 +date: 2024-11-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 cb2b856eeebd3..eb98a295545b8 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: 2024-11-10 +date: 2024-11-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 7f4299632010c..bb64c3093d652 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: 2024-11-10 +date: 2024-11-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 057695d3c3f88..d16af22e2b35c 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: 2024-11-10 +date: 2024-11-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 38972a956d976..d751d31185d18 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: 2024-11-10 +date: 2024-11-12 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 5bd3d50643124..0951e09a7e459 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_quality.mdx b/api_docs/data_quality.mdx index 8219e0f0e96a2..0d5b37eda3c08 100644 --- a/api_docs/data_quality.mdx +++ b/api_docs/data_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataQuality title: "dataQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the dataQuality plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataQuality'] --- import dataQualityObj from './data_quality.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index edb8c7449f51c..a524ed87dd39c 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: 2024-11-10 +date: 2024-11-12 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 4b2a71c75be0e..4801aeb146871 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_usage.mdx b/api_docs/data_usage.mdx index 112703ea492e3..ca09f822938cc 100644 --- a/api_docs/data_usage.mdx +++ b/api_docs/data_usage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataUsage title: "dataUsage" image: https://source.unsplash.com/400x175/?github description: API docs for the dataUsage plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataUsage'] --- import dataUsageObj from './data_usage.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index da326b4c23f54..287eeb2826c4d 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: 2024-11-10 +date: 2024-11-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 4c844be76ca42..97d8efb2e4f7f 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: 2024-11-10 +date: 2024-11-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 3cd0e5edcb0ad..d9bfe3d162572 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: 2024-11-10 +date: 2024-11-12 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 4a6d3e0cc8aa3..e06438b19b31f 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: 2024-11-10 +date: 2024-11-12 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 0a7c4debd41fd..92e6d765b7712 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index 9d1c36d907a7e..781077b90fbde 100644 --- a/api_docs/dataset_quality.mdx +++ b/api_docs/dataset_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/datasetQuality title: "datasetQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the datasetQuality plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'datasetQuality'] --- import datasetQualityObj from './dataset_quality.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index a33d8fa45cb88..b8625def2dbb2 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -158,6 +158,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | security | - | | | observabilityShared | - | | | @kbn/react-kibana-context-styled, kibanaReact | - | +| | indexLifecycleManagement | - | | | @kbn/reporting-public, discover | - | | | discover, @kbn/management-settings-field-definition | - | | | @kbn/content-management-table-list-view, filesManagement | - | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 77c822765565d..efc3f2961fa62 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -944,6 +944,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [license.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/server/services/license.ts#:~:text=license%24) | 8.8.0 | +| | [mocks.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/__jest__/mocks.ts#:~:text=max_size), [deserializer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts#:~:text=max_size), [deserializer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts#:~:text=max_size), [deserializer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts#:~:text=max_size), [serializer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts#:~:text=max_size), [serializer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts#:~:text=max_size), [serializer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts#:~:text=max_size), [serializer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts#:~:text=max_size), [rollover.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_flyout/components/rollover.tsx#:~:text=max_size), [rollover.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_flyout/components/rollover.tsx#:~:text=max_size)+ 7 more | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 44e1d57c4d6b4..5c53f577e6b0d 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 2a5a9fd0b5013..4b27de358490f 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: 2024-11-10 +date: 2024-11-12 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 ec8ee31563419..e160bb054f6e9 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: 2024-11-10 +date: 2024-11-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 2678f6133ba75..29651f5536a56 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/discover_shared.mdx b/api_docs/discover_shared.mdx index 4329bc6ffc136..e739cfef4d204 100644 --- a/api_docs/discover_shared.mdx +++ b/api_docs/discover_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverShared title: "discoverShared" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverShared plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverShared'] --- import discoverSharedObj from './discover_shared.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index e7e55ffc348e9..a5890f386a494 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.devdocs.json b/api_docs/elastic_assistant.devdocs.json index 4df33db88b4dc..3fe39450a7c86 100644 --- a/api_docs/elastic_assistant.devdocs.json +++ b/api_docs/elastic_assistant.devdocs.json @@ -1683,6 +1683,27 @@ "path": "x-pack/plugins/elastic_assistant/server/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "elasticAssistant", + "id": "def-server.AssistantToolParams.telemetry", + "type": "Object", + "tags": [], + "label": "telemetry", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-analytics-server", + "scope": "server", + "docId": "kibKbnCoreAnalyticsServerPluginApi", + "section": "def-server.AnalyticsServiceSetup", + "text": "AnalyticsServiceSetup" + }, + " | undefined" + ], + "path": "x-pack/plugins/elastic_assistant/server/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index 219732e07f1a7..d15d05811d128 100644 --- a/api_docs/elastic_assistant.mdx +++ b/api_docs/elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/elasticAssistant title: "elasticAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the elasticAssistant plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 52 | 0 | 37 | 2 | +| 53 | 0 | 38 | 2 | ## Server diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index c2b12a40e8e2d..99fe95318c4d7 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: 2024-11-10 +date: 2024-11-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 2fcf287eeea72..38e3f8964dbff 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: 2024-11-10 +date: 2024-11-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 34902ffc87542..01184c77221c1 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: 2024-11-10 +date: 2024-11-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 4c644bbd2a7fe..6e845c5eacbc6 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/entities_data_access.mdx b/api_docs/entities_data_access.mdx index 96d31ff61676a..3aa1ca62de527 100644 --- a/api_docs/entities_data_access.mdx +++ b/api_docs/entities_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/entitiesDataAccess title: "entitiesDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the entitiesDataAccess plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'entitiesDataAccess'] --- import entitiesDataAccessObj from './entities_data_access.devdocs.json'; diff --git a/api_docs/entity_manager.mdx b/api_docs/entity_manager.mdx index 80d39444e3f24..6eed6037e5596 100644 --- a/api_docs/entity_manager.mdx +++ b/api_docs/entity_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/entityManager title: "entityManager" image: https://source.unsplash.com/400x175/?github description: API docs for the entityManager plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'entityManager'] --- import entityManagerObj from './entity_manager.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 6b499b4ec061a..dcbbd723d4788 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/esql.mdx b/api_docs/esql.mdx index c2bd5fb7c2883..9ba78a7576131 100644 --- a/api_docs/esql.mdx +++ b/api_docs/esql.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esql title: "esql" image: https://source.unsplash.com/400x175/?github description: API docs for the esql plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esql'] --- import esqlObj from './esql.devdocs.json'; diff --git a/api_docs/esql_data_grid.mdx b/api_docs/esql_data_grid.mdx index 0a11cabffc494..4127d6baa15d0 100644 --- a/api_docs/esql_data_grid.mdx +++ b/api_docs/esql_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esqlDataGrid title: "esqlDataGrid" image: https://source.unsplash.com/400x175/?github description: API docs for the esqlDataGrid plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esqlDataGrid'] --- import esqlDataGridObj from './esql_data_grid.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 3dad1639c3440..4b25969e72390 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_annotation_listing.mdx b/api_docs/event_annotation_listing.mdx index 2d89eb0a36e36..253efc5daaec6 100644 --- a/api_docs/event_annotation_listing.mdx +++ b/api_docs/event_annotation_listing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotationListing title: "eventAnnotationListing" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotationListing plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotationListing'] --- import eventAnnotationListingObj from './event_annotation_listing.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 5623928823818..3e9e78585d719 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: 2024-11-10 +date: 2024-11-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 ad594d8eae248..6a8a5f76c1627 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: 2024-11-10 +date: 2024-11-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 3fa12da3b6f4c..eebaeb3c69fcf 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: 2024-11-10 +date: 2024-11-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 a57baa99df7e2..fc1020122f579 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: 2024-11-10 +date: 2024-11-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 dc96b1dca4233..91104c370d99c 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: 2024-11-10 +date: 2024-11-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 2b9d36efb1cd8..ed1c4f3b36823 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: 2024-11-10 +date: 2024-11-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 062a359c07041..f020c2fbac32a 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: 2024-11-10 +date: 2024-11-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 e228884ecf8e3..7b41cedd0de58 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: 2024-11-10 +date: 2024-11-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 9995780f2d10e..e26c63b99c972 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: 2024-11-10 +date: 2024-11-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 d6778f916fd7a..c9b73f9a57e97 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: 2024-11-10 +date: 2024-11-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 2e9dd01c5b8b0..c77344c8f7daa 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: 2024-11-10 +date: 2024-11-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 602aa5d157db8..5a6f58e76de97 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: 2024-11-10 +date: 2024-11-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 6a548c164d4f9..f4e196a5756be 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: 2024-11-10 +date: 2024-11-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 49b120429a5dc..379cad7b3b684 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: 2024-11-10 +date: 2024-11-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 f1d557a4bf68f..e98d44b5029a5 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: 2024-11-10 +date: 2024-11-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 fc5b5c3d3279f..955e3bd1bb776 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: 2024-11-10 +date: 2024-11-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 ea2d7c08dffce..0411c023a941d 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: 2024-11-10 +date: 2024-11-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 7dfcb56035a8e..2152f8c9eb64e 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/fields_metadata.mdx b/api_docs/fields_metadata.mdx index e6d3c3ad2d3c5..182306396fd24 100644 --- a/api_docs/fields_metadata.mdx +++ b/api_docs/fields_metadata.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldsMetadata title: "fieldsMetadata" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldsMetadata plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldsMetadata'] --- import fieldsMetadataObj from './fields_metadata.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 67163b1958f1a..2ac8c1ad62ae3 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: 2024-11-10 +date: 2024-11-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 ca4b9fcd4b375..25d75fea904e0 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: 2024-11-10 +date: 2024-11-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 af60e318bbf03..e7259ba5ea618 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: 2024-11-10 +date: 2024-11-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 f16b5191e3841..f9f9b010bdb5a 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: 2024-11-10 +date: 2024-11-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 9b73fc69d72b3..bd4663eb054b5 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: 2024-11-10 +date: 2024-11-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 14001b4740c04..e0a6f3f5deddc 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: 2024-11-10 +date: 2024-11-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 12e511babd65f..1750cc9c48396 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: 2024-11-10 +date: 2024-11-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 afd91c27c6912..b27ee510657c0 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.devdocs.json b/api_docs/index_lifecycle_management.devdocs.json index 03825ec75860a..d7ec7a91677c2 100644 --- a/api_docs/index_lifecycle_management.devdocs.json +++ b/api_docs/index_lifecycle_management.devdocs.json @@ -76,7 +76,7 @@ "signature": [ "\"ILM_LOCATOR_ID\"" ], - "path": "x-pack/plugins/index_lifecycle_management/public/locator.ts", + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/index.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 9b94ace7a2c6b..2ac0dcfaf98a6 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: 2024-11-10 +date: 2024-11-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 54c5753290ada..3cbc9017267c4 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/inference.mdx b/api_docs/inference.mdx index cb96958e814ef..5889e24b72ce6 100644 --- a/api_docs/inference.mdx +++ b/api_docs/inference.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inference title: "inference" image: https://source.unsplash.com/400x175/?github description: API docs for the inference plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inference'] --- import inferenceObj from './inference.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index a7a9de549fbf2..bb0c9357874cb 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/ingest_pipelines.mdx b/api_docs/ingest_pipelines.mdx index b04c6138150da..8b52232dfdde9 100644 --- a/api_docs/ingest_pipelines.mdx +++ b/api_docs/ingest_pipelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ingestPipelines title: "ingestPipelines" image: https://source.unsplash.com/400x175/?github description: API docs for the ingestPipelines plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ingestPipelines'] --- import ingestPipelinesObj from './ingest_pipelines.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index ef3c3275c8a17..27ac4506fff07 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/integration_assistant.mdx b/api_docs/integration_assistant.mdx index 1aafdf3098a88..ce73de5a54c48 100644 --- a/api_docs/integration_assistant.mdx +++ b/api_docs/integration_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/integrationAssistant title: "integrationAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the integrationAssistant plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'integrationAssistant'] --- import integrationAssistantObj from './integration_assistant.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index d77b22bf57341..fc5f400d8fcf2 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/inventory.mdx b/api_docs/inventory.mdx index 31f826ee9e7e0..a990a02009d58 100644 --- a/api_docs/inventory.mdx +++ b/api_docs/inventory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inventory title: "inventory" image: https://source.unsplash.com/400x175/?github description: API docs for the inventory plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inventory'] --- import inventoryObj from './inventory.devdocs.json'; diff --git a/api_docs/investigate.mdx b/api_docs/investigate.mdx index 3bae92a3195a4..741c6e1c5114b 100644 --- a/api_docs/investigate.mdx +++ b/api_docs/investigate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/investigate title: "investigate" image: https://source.unsplash.com/400x175/?github description: API docs for the investigate plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'investigate'] --- import investigateObj from './investigate.devdocs.json'; diff --git a/api_docs/investigate_app.mdx b/api_docs/investigate_app.mdx index f4f668b214000..f0ae814454ee3 100644 --- a/api_docs/investigate_app.mdx +++ b/api_docs/investigate_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/investigateApp title: "investigateApp" image: https://source.unsplash.com/400x175/?github description: API docs for the investigateApp plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'investigateApp'] --- import investigateAppObj from './investigate_app.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index 3a44e27c1752c..323a0f2db579c 100644 --- a/api_docs/kbn_actions_types.mdx +++ b/api_docs/kbn_actions_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-actions-types title: "@kbn/actions-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/actions-types plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_ai_assistant.mdx b/api_docs/kbn_ai_assistant.mdx index 6fbd0bc24eaec..b507eb315eda5 100644 --- a/api_docs/kbn_ai_assistant.mdx +++ b/api_docs/kbn_ai_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ai-assistant title: "@kbn/ai-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ai-assistant plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ai-assistant'] --- import kbnAiAssistantObj from './kbn_ai_assistant.devdocs.json'; diff --git a/api_docs/kbn_ai_assistant_common.mdx b/api_docs/kbn_ai_assistant_common.mdx index 42c0153a9c304..edacea1dc39f0 100644 --- a/api_docs/kbn_ai_assistant_common.mdx +++ b/api_docs/kbn_ai_assistant_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ai-assistant-common title: "@kbn/ai-assistant-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ai-assistant-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ai-assistant-common'] --- import kbnAiAssistantCommonObj from './kbn_ai_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 1ffa0789a764d..cc29b5ba5dfa6 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_log_pattern_analysis.mdx b/api_docs/kbn_aiops_log_pattern_analysis.mdx index 3818bafb385b3..6a83be2ef6cc4 100644 --- a/api_docs/kbn_aiops_log_pattern_analysis.mdx +++ b/api_docs/kbn_aiops_log_pattern_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-pattern-analysis title: "@kbn/aiops-log-pattern-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-pattern-analysis plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-pattern-analysis'] --- import kbnAiopsLogPatternAnalysisObj from './kbn_aiops_log_pattern_analysis.devdocs.json'; diff --git a/api_docs/kbn_aiops_log_rate_analysis.mdx b/api_docs/kbn_aiops_log_rate_analysis.mdx index 48e0fb0e69db2..b6d2c0ec0a601 100644 --- a/api_docs/kbn_aiops_log_rate_analysis.mdx +++ b/api_docs/kbn_aiops_log_rate_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-rate-analysis title: "@kbn/aiops-log-rate-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-rate-analysis plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-rate-analysis'] --- import kbnAiopsLogRateAnalysisObj from './kbn_aiops_log_rate_analysis.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 34544911e0f1e..a0a848dc35bd4 100644 --- a/api_docs/kbn_alerting_api_integration_helpers.mdx +++ b/api_docs/kbn_alerting_api_integration_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-api-integration-helpers title: "@kbn/alerting-api-integration-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-api-integration-helpers plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-api-integration-helpers'] --- import kbnAlertingApiIntegrationHelpersObj from './kbn_alerting_api_integration_helpers.devdocs.json'; diff --git a/api_docs/kbn_alerting_comparators.mdx b/api_docs/kbn_alerting_comparators.mdx index 52eef1d8bdca3..73454eb6b033b 100644 --- a/api_docs/kbn_alerting_comparators.mdx +++ b/api_docs/kbn_alerting_comparators.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-comparators title: "@kbn/alerting-comparators" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-comparators plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-comparators'] --- import kbnAlertingComparatorsObj from './kbn_alerting_comparators.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 70984e50600e9..69d5ec23230a4 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: 2024-11-10 +date: 2024-11-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_alerting_types.mdx b/api_docs/kbn_alerting_types.mdx index cdcf09268a18f..84c78d006a983 100644 --- a/api_docs/kbn_alerting_types.mdx +++ b/api_docs/kbn_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-types title: "@kbn/alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-types plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-types'] --- import kbnAlertingTypesObj from './kbn_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 22f3669564655..c52f50b5e9959 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: 2024-11-10 +date: 2024-11-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_grouping.mdx b/api_docs/kbn_alerts_grouping.mdx index 438f3260b4fff..9b7d661ebb624 100644 --- a/api_docs/kbn_alerts_grouping.mdx +++ b/api_docs/kbn_alerts_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-grouping title: "@kbn/alerts-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-grouping plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-grouping'] --- import kbnAlertsGroupingObj from './kbn_alerts_grouping.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 71f7a2c838df7..d57b0582b6a6d 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: 2024-11-10 +date: 2024-11-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 4540cb045209a..b2ee2ae503c52 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index c816ae99747c6..d82b56b24aeb0 100644 --- a/api_docs/kbn_analytics_collection_utils.mdx +++ b/api_docs/kbn_analytics_collection_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-collection-utils title: "@kbn/analytics-collection-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-collection-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index df615ee1d7c77..62d47b008ad51 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: 2024-11-10 +date: 2024-11-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_data_view.mdx b/api_docs/kbn_apm_data_view.mdx index 798ccf69a5ecd..065e099e353a7 100644 --- a/api_docs/kbn_apm_data_view.mdx +++ b/api_docs/kbn_apm_data_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-data-view title: "@kbn/apm-data-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-data-view plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-data-view'] --- import kbnApmDataViewObj from './kbn_apm_data_view.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index ab90bf6a85d0e..9edda86620a6d 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: 2024-11-10 +date: 2024-11-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 48e740cc6c6d1..b22847579b95d 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: 2024-11-10 +date: 2024-11-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_types.mdx b/api_docs/kbn_apm_types.mdx index 2042138edca0e..f018b4dc4f250 100644 --- a/api_docs/kbn_apm_types.mdx +++ b/api_docs/kbn_apm_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-types title: "@kbn/apm-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-types plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-types'] --- import kbnApmTypesObj from './kbn_apm_types.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 2a2b9e51fedff..5b84cbd3e3213 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_avc_banner.mdx b/api_docs/kbn_avc_banner.mdx index f4d4fb1ccafb8..964a8d376ae00 100644 --- a/api_docs/kbn_avc_banner.mdx +++ b/api_docs/kbn_avc_banner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-avc-banner title: "@kbn/avc-banner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/avc-banner plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/avc-banner'] --- import kbnAvcBannerObj from './kbn_avc_banner.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index c4ef1fba843ff..e93dd4df949e5 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_bfetch_error.mdx b/api_docs/kbn_bfetch_error.mdx index c4ef81d688a4e..3b4644bfed2bc 100644 --- a/api_docs/kbn_bfetch_error.mdx +++ b/api_docs/kbn_bfetch_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-bfetch-error title: "@kbn/bfetch-error" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/bfetch-error plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bfetch-error'] --- import kbnBfetchErrorObj from './kbn_bfetch_error.devdocs.json'; diff --git a/api_docs/kbn_calculate_auto.mdx b/api_docs/kbn_calculate_auto.mdx index bfe80a5f473f8..e20024ebcc43b 100644 --- a/api_docs/kbn_calculate_auto.mdx +++ b/api_docs/kbn_calculate_auto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-auto title: "@kbn/calculate-auto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-auto plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-auto'] --- import kbnCalculateAutoObj from './kbn_calculate_auto.devdocs.json'; diff --git a/api_docs/kbn_calculate_width_from_char_count.mdx b/api_docs/kbn_calculate_width_from_char_count.mdx index bb02d73d56839..4e2600cb02f1c 100644 --- a/api_docs/kbn_calculate_width_from_char_count.mdx +++ b/api_docs/kbn_calculate_width_from_char_count.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-width-from-char-count title: "@kbn/calculate-width-from-char-count" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-width-from-char-count plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-width-from-char-count'] --- import kbnCalculateWidthFromCharCountObj from './kbn_calculate_width_from_char_count.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index d75f35e508612..e1f2327ed7322 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cbor.mdx b/api_docs/kbn_cbor.mdx index d3ded1babe109..d183f1aefe14b 100644 --- a/api_docs/kbn_cbor.mdx +++ b/api_docs/kbn_cbor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cbor title: "@kbn/cbor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cbor plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cbor'] --- import kbnCborObj from './kbn_cbor.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index 59bd083939865..320ae236f19c9 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: 2024-11-10 +date: 2024-11-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 fe7496fa5fc48..1804025bc6e2a 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: 2024-11-10 +date: 2024-11-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 5c61643fe28d0..2abd21bd4910e 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: 2024-11-10 +date: 2024-11-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 4ecf454766655..f2165c99ee6a0 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: 2024-11-10 +date: 2024-11-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 6207ba4708f5c..ca26b29a55040 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: 2024-11-10 +date: 2024-11-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 1140ef95f9154..0716b421c75d7 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: 2024-11-10 +date: 2024-11-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 54d2e9a9a1bd5..6d608449b7e06 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: 2024-11-10 +date: 2024-11-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_cloud_security_posture.mdx b/api_docs/kbn_cloud_security_posture.mdx index 2105d0f705b2e..5a39b4863ce86 100644 --- a/api_docs/kbn_cloud_security_posture.mdx +++ b/api_docs/kbn_cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture title: "@kbn/cloud-security-posture" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture'] --- import kbnCloudSecurityPostureObj from './kbn_cloud_security_posture.devdocs.json'; diff --git a/api_docs/kbn_cloud_security_posture_common.mdx b/api_docs/kbn_cloud_security_posture_common.mdx index e0419e12a5953..980f1e79d34c0 100644 --- a/api_docs/kbn_cloud_security_posture_common.mdx +++ b/api_docs/kbn_cloud_security_posture_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture-common title: "@kbn/cloud-security-posture-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture-common'] --- import kbnCloudSecurityPostureCommonObj from './kbn_cloud_security_posture_common.devdocs.json'; diff --git a/api_docs/kbn_cloud_security_posture_graph.mdx b/api_docs/kbn_cloud_security_posture_graph.mdx index da7b99c4d816d..a9807078c1778 100644 --- a/api_docs/kbn_cloud_security_posture_graph.mdx +++ b/api_docs/kbn_cloud_security_posture_graph.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture-graph title: "@kbn/cloud-security-posture-graph" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture-graph plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture-graph'] --- import kbnCloudSecurityPostureGraphObj from './kbn_cloud_security_posture_graph.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 2dbe9958c30ae..353c1146fc6e3 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: 2024-11-10 +date: 2024-11-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_mock.mdx b/api_docs/kbn_code_editor_mock.mdx index 65fb7e960dc50..7b994f1c7fe5a 100644 --- a/api_docs/kbn_code_editor_mock.mdx +++ b/api_docs/kbn_code_editor_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mock title: "@kbn/code-editor-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mock plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mock'] --- import kbnCodeEditorMockObj from './kbn_code_editor_mock.devdocs.json'; diff --git a/api_docs/kbn_code_owners.mdx b/api_docs/kbn_code_owners.mdx index adfab103c2a09..c0502db23115e 100644 --- a/api_docs/kbn_code_owners.mdx +++ b/api_docs/kbn_code_owners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-owners title: "@kbn/code-owners" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-owners plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index bacd8d90cbd72..c38e34841f10d 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: 2024-11-10 +date: 2024-11-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 872211553bbfe..36df67b11013f 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: 2024-11-10 +date: 2024-11-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 1347f9befa003..64dc10df0c3a7 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: 2024-11-10 +date: 2024-11-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 5d155ab7305da..b150c48b02ad7 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: 2024-11-10 +date: 2024-11-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 3722e6ade741d..d23fabc9adf00 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: 2024-11-10 +date: 2024-11-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_content_insights_public.mdx b/api_docs/kbn_content_management_content_insights_public.mdx index 99edfc129929a..1c65dad73ba53 100644 --- a/api_docs/kbn_content_management_content_insights_public.mdx +++ b/api_docs/kbn_content_management_content_insights_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-insights-public title: "@kbn/content-management-content-insights-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-insights-public plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-insights-public'] --- import kbnContentManagementContentInsightsPublicObj from './kbn_content_management_content_insights_public.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_insights_server.mdx b/api_docs/kbn_content_management_content_insights_server.mdx index 5082b4b2a6db1..12a392966e5c7 100644 --- a/api_docs/kbn_content_management_content_insights_server.mdx +++ b/api_docs/kbn_content_management_content_insights_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-insights-server title: "@kbn/content-management-content-insights-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-insights-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-insights-server'] --- import kbnContentManagementContentInsightsServerObj from './kbn_content_management_content_insights_server.devdocs.json'; diff --git a/api_docs/kbn_content_management_favorites_public.mdx b/api_docs/kbn_content_management_favorites_public.mdx index 5ce01aa6860d5..1bd4a4c16c00e 100644 --- a/api_docs/kbn_content_management_favorites_public.mdx +++ b/api_docs/kbn_content_management_favorites_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-favorites-public title: "@kbn/content-management-favorites-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-favorites-public plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-favorites-public'] --- import kbnContentManagementFavoritesPublicObj from './kbn_content_management_favorites_public.devdocs.json'; diff --git a/api_docs/kbn_content_management_favorites_server.mdx b/api_docs/kbn_content_management_favorites_server.mdx index f99ace4c6a7cb..1b8425c4c2983 100644 --- a/api_docs/kbn_content_management_favorites_server.mdx +++ b/api_docs/kbn_content_management_favorites_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-favorites-server title: "@kbn/content-management-favorites-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-favorites-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-favorites-server'] --- import kbnContentManagementFavoritesServerObj from './kbn_content_management_favorites_server.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 f061d59f9db2f..609458b5331d6 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: 2024-11-10 +date: 2024-11-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 8fddccb28f5e1..dc11375e8a814 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: 2024-11-10 +date: 2024-11-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_common.mdx b/api_docs/kbn_content_management_table_list_view_common.mdx index f1fdf635a4a74..c03a1ec3197c6 100644 --- a/api_docs/kbn_content_management_table_list_view_common.mdx +++ b/api_docs/kbn_content_management_table_list_view_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-common title: "@kbn/content-management-table-list-view-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-common'] --- import kbnContentManagementTableListViewCommonObj from './kbn_content_management_table_list_view_common.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 75317cbb18060..db646bd362929 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: 2024-11-10 +date: 2024-11-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_user_profiles.mdx b/api_docs/kbn_content_management_user_profiles.mdx index 59dc618b47aef..74795dd1d8906 100644 --- a/api_docs/kbn_content_management_user_profiles.mdx +++ b/api_docs/kbn_content_management_user_profiles.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-user-profiles title: "@kbn/content-management-user-profiles" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-user-profiles plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-user-profiles'] --- import kbnContentManagementUserProfilesObj from './kbn_content_management_user_profiles.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 88be3d0829e79..d00fea0e055b3 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: 2024-11-10 +date: 2024-11-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.devdocs.json b/api_docs/kbn_core_analytics_browser.devdocs.json index 288f48a4955a0..16e5bf6680c4d 100644 --- a/api_docs/kbn_core_analytics_browser.devdocs.json +++ b/api_docs/kbn_core_analytics_browser.devdocs.json @@ -702,9 +702,17 @@ "plugin": "datasetQuality", "path": "x-pack/plugins/observability_solution/dataset_quality/public/services/telemetry/telemetry_client.ts" }, + { + "plugin": "@kbn/langchain", + "path": "x-pack/packages/kbn-langchain/server/tracers/telemetry/telemetry_tracer.ts" + }, + { + "plugin": "elasticAssistant", + "path": "x-pack/plugins/elastic_assistant/server/ai_assistant_data_clients/knowledge_base/create_knowledge_base_entry.ts" + }, { "plugin": "elasticAssistant", - "path": "x-pack/plugins/elastic_assistant/server/routes/helpers.ts" + "path": "x-pack/plugins/elastic_assistant/server/ai_assistant_data_clients/knowledge_base/create_knowledge_base_entry.ts" }, { "plugin": "elasticAssistant", @@ -722,6 +730,10 @@ "plugin": "elasticAssistant", "path": "x-pack/plugins/elastic_assistant/server/routes/attack_discovery/post/helpers/handle_graph_error/index.tsx" }, + { + "plugin": "elasticAssistant", + "path": "x-pack/plugins/elastic_assistant/server/routes/knowledge_base/entries/bulk_actions_route.ts" + }, { "plugin": "globalSearchBar", "path": "x-pack/plugins/global_search_bar/public/telemetry/event_reporter.ts" @@ -796,151 +808,7 @@ }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" + "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_service.ts" }, { "plugin": "osquery", @@ -1170,6 +1038,14 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.test.ts" }, + { + "plugin": "@kbn/langchain", + "path": "x-pack/packages/kbn-langchain/server/tracers/telemetry/telemetry_tracer.test.ts" + }, + { + "plugin": "@kbn/langchain", + "path": "x-pack/packages/kbn-langchain/server/tracers/telemetry/telemetry_tracer.test.ts" + }, { "plugin": "@kbn/shared-ux-chrome-navigation", "path": "packages/shared-ux/chrome/navigation/mocks/storybook.ts" diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index c777392ba6175..9259732156ac4 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: 2024-11-10 +date: 2024-11-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 e39d17bc3110d..aa45f95180ae4 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: 2024-11-10 +date: 2024-11-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 0de9f23aa2f06..c0bd6d0cd5713 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: 2024-11-10 +date: 2024-11-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.devdocs.json b/api_docs/kbn_core_analytics_server.devdocs.json index c08c5dec164f0..f4eedf0c5ca75 100644 --- a/api_docs/kbn_core_analytics_server.devdocs.json +++ b/api_docs/kbn_core_analytics_server.devdocs.json @@ -710,9 +710,17 @@ "plugin": "datasetQuality", "path": "x-pack/plugins/observability_solution/dataset_quality/public/services/telemetry/telemetry_client.ts" }, + { + "plugin": "@kbn/langchain", + "path": "x-pack/packages/kbn-langchain/server/tracers/telemetry/telemetry_tracer.ts" + }, + { + "plugin": "elasticAssistant", + "path": "x-pack/plugins/elastic_assistant/server/ai_assistant_data_clients/knowledge_base/create_knowledge_base_entry.ts" + }, { "plugin": "elasticAssistant", - "path": "x-pack/plugins/elastic_assistant/server/routes/helpers.ts" + "path": "x-pack/plugins/elastic_assistant/server/ai_assistant_data_clients/knowledge_base/create_knowledge_base_entry.ts" }, { "plugin": "elasticAssistant", @@ -730,6 +738,10 @@ "plugin": "elasticAssistant", "path": "x-pack/plugins/elastic_assistant/server/routes/attack_discovery/post/helpers/handle_graph_error/index.tsx" }, + { + "plugin": "elasticAssistant", + "path": "x-pack/plugins/elastic_assistant/server/routes/knowledge_base/entries/bulk_actions_route.ts" + }, { "plugin": "globalSearchBar", "path": "x-pack/plugins/global_search_bar/public/telemetry/event_reporter.ts" @@ -804,151 +816,7 @@ }, { "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" - }, - { - "plugin": "securitySolution", - "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_client.ts" + "path": "x-pack/plugins/security_solution/public/common/lib/telemetry/telemetry_service.ts" }, { "plugin": "osquery", @@ -1178,6 +1046,14 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/endpoint/services/actions/clients/sentinelone/sentinel_one_actions_client.test.ts" }, + { + "plugin": "@kbn/langchain", + "path": "x-pack/packages/kbn-langchain/server/tracers/telemetry/telemetry_tracer.test.ts" + }, + { + "plugin": "@kbn/langchain", + "path": "x-pack/packages/kbn-langchain/server/tracers/telemetry/telemetry_tracer.test.ts" + }, { "plugin": "@kbn/shared-ux-chrome-navigation", "path": "packages/shared-ux/chrome/navigation/mocks/storybook.ts" diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 027b64516dd2e..ed1a968c83f5f 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: 2024-11-10 +date: 2024-11-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 ca52671875946..a439349d60a63 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: 2024-11-10 +date: 2024-11-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 528184e40fe62..04e2124bb9c97 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: 2024-11-10 +date: 2024-11-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 5544997621fc7..c5bc8ea96ebb9 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: 2024-11-10 +date: 2024-11-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 89b7c2b63cf08..8ca3a84902b6c 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: 2024-11-10 +date: 2024-11-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 e44459ba92ccb..b092910766ce2 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: 2024-11-10 +date: 2024-11-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 a59e0fd0122e9..8fbc068a47068 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: 2024-11-10 +date: 2024-11-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 d3facda9cceca..437494990ec64 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: 2024-11-10 +date: 2024-11-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 ae9b561db4abf..8360e30d68902 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: 2024-11-10 +date: 2024-11-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 c777532f6b07e..cad169815e480 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: 2024-11-10 +date: 2024-11-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 c7c42f06e30cc..74026cbd53e94 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: 2024-11-10 +date: 2024-11-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 43e7c3e5513f3..0240046659dea 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: 2024-11-10 +date: 2024-11-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 f19a27549639b..dd4240e077be4 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: 2024-11-10 +date: 2024-11-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 586c4f9c345cf..672f23c9f90df 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: 2024-11-10 +date: 2024-11-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 4ee4c2f5c8e4d..c785a618c178f 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: 2024-11-10 +date: 2024-11-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 dfa28b6a22f83..746a4b1c76639 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: 2024-11-10 +date: 2024-11-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 66420c5596455..aee86b1904408 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: 2024-11-10 +date: 2024-11-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 6e19e15f1a23f..7cf4a32d639c7 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: 2024-11-10 +date: 2024-11-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.devdocs.json b/api_docs/kbn_core_chrome_browser.devdocs.json index 33a27d209c1ae..3c3be73393fdb 100644 --- a/api_docs/kbn_core_chrome_browser.devdocs.json +++ b/api_docs/kbn_core_chrome_browser.devdocs.json @@ -3765,7 +3765,7 @@ "label": "AppDeepLinkId", "description": [], "signature": [ - "\"fleet\" | \"graph\" | \"ml\" | \"monitoring\" | \"profiling\" | \"metrics\" | \"management\" | \"apm\" | \"synthetics\" | \"ux\" | \"canvas\" | \"logs\" | \"dashboards\" | \"slo\" | \"observabilityAIAssistant\" | \"home\" | \"integrations\" | \"discover\" | \"observability-overview\" | \"appSearch\" | \"dev_tools\" | \"maps\" | \"visualize\" | \"dev_tools:console\" | \"dev_tools:searchprofiler\" | \"dev_tools:painless_lab\" | \"dev_tools:grokdebugger\" | \"ml:notifications\" | \"ml:nodes\" | \"ml:overview\" | \"ml:memoryUsage\" | \"ml:settings\" | \"ml:dataVisualizer\" | \"ml:logPatternAnalysis\" | \"ml:logRateAnalysis\" | \"ml:singleMetricViewer\" | \"ml:anomalyDetection\" | \"ml:anomalyExplorer\" | \"ml:dataDrift\" | \"ml:dataFrameAnalytics\" | \"ml:resultExplorer\" | \"ml:analyticsMap\" | \"ml:aiOps\" | \"ml:changePointDetections\" | \"ml:modelManagement\" | \"ml:nodesOverview\" | \"ml:esqlDataVisualizer\" | \"ml:fileUpload\" | \"ml:indexDataVisualizer\" | \"ml:calendarSettings\" | \"ml:filterListsSettings\" | \"ml:suppliedConfigurations\" | \"osquery\" | \"management:transform\" | \"management:watcher\" | \"management:cases\" | \"management:tags\" | \"management:maintenanceWindows\" | \"management:cross_cluster_replication\" | \"management:dataViews\" | \"management:spaces\" | \"management:settings\" | \"management:users\" | \"management:migrate_data\" | \"management:search_sessions\" | \"management:data_quality\" | \"management:filesManagement\" | \"management:roles\" | \"management:reporting\" | \"management:aiAssistantManagementSelection\" | \"management:securityAiAssistantManagement\" | \"management:observabilityAiAssistantManagement\" | \"management:api_keys\" | \"management:license_management\" | \"management:index_lifecycle_management\" | \"management:index_management\" | \"management:ingest_pipelines\" | \"management:jobsListLink\" | \"management:objects\" | \"management:pipelines\" | \"management:remote_clusters\" | \"management:role_mappings\" | \"management:rollup_jobs\" | \"management:snapshot_restore\" | \"management:triggersActions\" | \"management:triggersActionsConnectors\" | \"management:upgrade_assistant\" | \"enterpriseSearch\" | \"enterpriseSearchContent\" | \"enterpriseSearchApplications\" | \"searchInferenceEndpoints\" | \"enterpriseSearchAnalytics\" | \"workplaceSearch\" | \"serverlessElasticsearch\" | \"serverlessConnectors\" | \"searchPlayground\" | \"searchHomepage\" | \"enterpriseSearchContent:connectors\" | \"enterpriseSearchContent:searchIndices\" | \"enterpriseSearchContent:webCrawlers\" | \"enterpriseSearchApplications:searchApplications\" | \"enterpriseSearchApplications:playground\" | \"appSearch:engines\" | \"searchInferenceEndpoints:inferenceEndpoints\" | \"elasticsearchStart\" | \"elasticsearchIndices\" | \"enterpriseSearchElasticsearch\" | \"enterpriseSearchVectorSearch\" | \"enterpriseSearchSemanticSearch\" | \"enterpriseSearchAISearch\" | \"observability-logs-explorer\" | \"last-used-logs-viewer\" | \"observabilityOnboarding\" | \"inventory\" | \"logs:settings\" | \"logs:stream\" | \"logs:log-categories\" | \"logs:anomalies\" | \"observability-overview:cases\" | \"observability-overview:alerts\" | \"observability-overview:rules\" | \"observability-overview:cases_create\" | \"observability-overview:cases_configure\" | \"metrics:settings\" | \"metrics:hosts\" | \"metrics:inventory\" | \"metrics:metrics-explorer\" | \"metrics:assetDetails\" | \"apm:services\" | \"apm:traces\" | \"apm:dependencies\" | \"apm:service-map\" | \"apm:settings\" | \"apm:service-groups-list\" | \"apm:storage-explorer\" | \"synthetics:overview\" | \"synthetics:certificates\" | \"profiling:functions\" | \"profiling:stacktraces\" | \"profiling:flamegraphs\" | \"inventory:datastreams\" | \"securitySolutionUI\" | \"securitySolutionUI:\" | \"securitySolutionUI:cases\" | \"securitySolutionUI:alerts\" | \"securitySolutionUI:rules\" | \"securitySolutionUI:policy\" | \"securitySolutionUI:overview\" | \"securitySolutionUI:dashboards\" | \"securitySolutionUI:kubernetes\" | \"securitySolutionUI:cases_create\" | \"securitySolutionUI:cases_configure\" | \"securitySolutionUI:hosts\" | \"securitySolutionUI:users\" | \"securitySolutionUI:cloud_defend-policies\" | \"securitySolutionUI:cloud_security_posture-dashboard\" | \"securitySolutionUI:cloud_security_posture-findings\" | \"securitySolutionUI:cloud_security_posture-benchmarks\" | \"securitySolutionUI:network\" | \"securitySolutionUI:data_quality\" | \"securitySolutionUI:explore\" | \"securitySolutionUI:assets\" | \"securitySolutionUI:cloud_defend\" | \"securitySolutionUI:notes\" | \"securitySolutionUI:administration\" | \"securitySolutionUI:attack_discovery\" | \"securitySolutionUI:blocklist\" | \"securitySolutionUI:cloud_security_posture-rules\" | \"securitySolutionUI:detections\" | \"securitySolutionUI:detection_response\" | \"securitySolutionUI:endpoints\" | \"securitySolutionUI:event_filters\" | \"securitySolutionUI:exceptions\" | \"securitySolutionUI:host_isolation_exceptions\" | \"securitySolutionUI:hosts-all\" | \"securitySolutionUI:hosts-anomalies\" | \"securitySolutionUI:hosts-risk\" | \"securitySolutionUI:hosts-events\" | \"securitySolutionUI:hosts-sessions\" | \"securitySolutionUI:hosts-uncommon_processes\" | \"securitySolutionUI:investigations\" | \"securitySolutionUI:get_started\" | \"securitySolutionUI:machine_learning-landing\" | \"securitySolutionUI:network-anomalies\" | \"securitySolutionUI:network-dns\" | \"securitySolutionUI:network-events\" | \"securitySolutionUI:network-flows\" | \"securitySolutionUI:network-http\" | \"securitySolutionUI:network-tls\" | \"securitySolutionUI:response_actions_history\" | \"securitySolutionUI:rules-add\" | \"securitySolutionUI:rules-create\" | \"securitySolutionUI:rules-landing\" | \"securitySolutionUI:threat_intelligence\" | \"securitySolutionUI:timelines\" | \"securitySolutionUI:timelines-templates\" | \"securitySolutionUI:trusted_apps\" | \"securitySolutionUI:users-all\" | \"securitySolutionUI:users-anomalies\" | \"securitySolutionUI:users-authentications\" | \"securitySolutionUI:users-events\" | \"securitySolutionUI:users-risk\" | \"securitySolutionUI:entity_analytics\" | \"securitySolutionUI:entity_analytics-management\" | \"securitySolutionUI:entity_analytics-asset-classification\" | \"securitySolutionUI:entity_analytics-entity_store_management\" | \"securitySolutionUI:coverage-overview\" | \"fleet:settings\" | \"fleet:agents\" | \"fleet:policies\" | \"fleet:data_streams\" | \"fleet:enrollment_tokens\" | \"fleet:uninstall_tokens\"" + "\"fleet\" | \"graph\" | \"ml\" | \"monitoring\" | \"profiling\" | \"metrics\" | \"management\" | \"apm\" | \"synthetics\" | \"ux\" | \"canvas\" | \"logs\" | \"dashboards\" | \"slo\" | \"observabilityAIAssistant\" | \"home\" | \"integrations\" | \"discover\" | \"observability-overview\" | \"appSearch\" | \"dev_tools\" | \"maps\" | \"visualize\" | \"dev_tools:console\" | \"dev_tools:searchprofiler\" | \"dev_tools:painless_lab\" | \"dev_tools:grokdebugger\" | \"ml:notifications\" | \"ml:nodes\" | \"ml:overview\" | \"ml:memoryUsage\" | \"ml:settings\" | \"ml:dataVisualizer\" | \"ml:logPatternAnalysis\" | \"ml:logRateAnalysis\" | \"ml:singleMetricViewer\" | \"ml:anomalyDetection\" | \"ml:anomalyExplorer\" | \"ml:dataDrift\" | \"ml:dataFrameAnalytics\" | \"ml:resultExplorer\" | \"ml:analyticsMap\" | \"ml:aiOps\" | \"ml:changePointDetections\" | \"ml:modelManagement\" | \"ml:nodesOverview\" | \"ml:esqlDataVisualizer\" | \"ml:fileUpload\" | \"ml:indexDataVisualizer\" | \"ml:calendarSettings\" | \"ml:filterListsSettings\" | \"ml:suppliedConfigurations\" | \"osquery\" | \"management:transform\" | \"management:watcher\" | \"management:cases\" | \"management:tags\" | \"management:maintenanceWindows\" | \"management:cross_cluster_replication\" | \"management:dataViews\" | \"management:spaces\" | \"management:settings\" | \"management:users\" | \"management:migrate_data\" | \"management:search_sessions\" | \"management:data_quality\" | \"management:filesManagement\" | \"management:roles\" | \"management:reporting\" | \"management:aiAssistantManagementSelection\" | \"management:securityAiAssistantManagement\" | \"management:observabilityAiAssistantManagement\" | \"management:api_keys\" | \"management:license_management\" | \"management:index_lifecycle_management\" | \"management:index_management\" | \"management:ingest_pipelines\" | \"management:jobsListLink\" | \"management:objects\" | \"management:pipelines\" | \"management:remote_clusters\" | \"management:role_mappings\" | \"management:rollup_jobs\" | \"management:snapshot_restore\" | \"management:triggersActions\" | \"management:triggersActionsConnectors\" | \"management:upgrade_assistant\" | \"enterpriseSearch\" | \"enterpriseSearchContent\" | \"enterpriseSearchApplications\" | \"searchInferenceEndpoints\" | \"enterpriseSearchAnalytics\" | \"workplaceSearch\" | \"serverlessElasticsearch\" | \"serverlessConnectors\" | \"searchPlayground\" | \"searchHomepage\" | \"enterpriseSearchContent:connectors\" | \"enterpriseSearchContent:searchIndices\" | \"enterpriseSearchContent:webCrawlers\" | \"enterpriseSearchApplications:searchApplications\" | \"enterpriseSearchApplications:playground\" | \"appSearch:engines\" | \"searchInferenceEndpoints:inferenceEndpoints\" | \"elasticsearchStart\" | \"elasticsearchIndices\" | \"enterpriseSearchElasticsearch\" | \"enterpriseSearchVectorSearch\" | \"enterpriseSearchSemanticSearch\" | \"enterpriseSearchAISearch\" | \"elasticsearchIndices:createIndex\" | \"observability-logs-explorer\" | \"last-used-logs-viewer\" | \"observabilityOnboarding\" | \"inventory\" | \"logs:settings\" | \"logs:stream\" | \"logs:log-categories\" | \"logs:anomalies\" | \"observability-overview:cases\" | \"observability-overview:alerts\" | \"observability-overview:rules\" | \"observability-overview:cases_create\" | \"observability-overview:cases_configure\" | \"metrics:settings\" | \"metrics:hosts\" | \"metrics:inventory\" | \"metrics:metrics-explorer\" | \"metrics:assetDetails\" | \"apm:services\" | \"apm:traces\" | \"apm:dependencies\" | \"apm:service-map\" | \"apm:settings\" | \"apm:service-groups-list\" | \"apm:storage-explorer\" | \"synthetics:overview\" | \"synthetics:certificates\" | \"profiling:functions\" | \"profiling:stacktraces\" | \"profiling:flamegraphs\" | \"inventory:datastreams\" | \"securitySolutionUI\" | \"securitySolutionUI:\" | \"securitySolutionUI:cases\" | \"securitySolutionUI:alerts\" | \"securitySolutionUI:rules\" | \"securitySolutionUI:policy\" | \"securitySolutionUI:overview\" | \"securitySolutionUI:dashboards\" | \"securitySolutionUI:kubernetes\" | \"securitySolutionUI:cases_create\" | \"securitySolutionUI:cases_configure\" | \"securitySolutionUI:hosts\" | \"securitySolutionUI:users\" | \"securitySolutionUI:cloud_defend-policies\" | \"securitySolutionUI:cloud_security_posture-dashboard\" | \"securitySolutionUI:cloud_security_posture-findings\" | \"securitySolutionUI:cloud_security_posture-benchmarks\" | \"securitySolutionUI:network\" | \"securitySolutionUI:data_quality\" | \"securitySolutionUI:explore\" | \"securitySolutionUI:assets\" | \"securitySolutionUI:cloud_defend\" | \"securitySolutionUI:notes\" | \"securitySolutionUI:administration\" | \"securitySolutionUI:attack_discovery\" | \"securitySolutionUI:blocklist\" | \"securitySolutionUI:cloud_security_posture-rules\" | \"securitySolutionUI:detections\" | \"securitySolutionUI:detection_response\" | \"securitySolutionUI:endpoints\" | \"securitySolutionUI:event_filters\" | \"securitySolutionUI:exceptions\" | \"securitySolutionUI:host_isolation_exceptions\" | \"securitySolutionUI:hosts-all\" | \"securitySolutionUI:hosts-anomalies\" | \"securitySolutionUI:hosts-risk\" | \"securitySolutionUI:hosts-events\" | \"securitySolutionUI:hosts-sessions\" | \"securitySolutionUI:hosts-uncommon_processes\" | \"securitySolutionUI:investigations\" | \"securitySolutionUI:get_started\" | \"securitySolutionUI:machine_learning-landing\" | \"securitySolutionUI:network-anomalies\" | \"securitySolutionUI:network-dns\" | \"securitySolutionUI:network-events\" | \"securitySolutionUI:network-flows\" | \"securitySolutionUI:network-http\" | \"securitySolutionUI:network-tls\" | \"securitySolutionUI:response_actions_history\" | \"securitySolutionUI:rules-add\" | \"securitySolutionUI:rules-create\" | \"securitySolutionUI:rules-landing\" | \"securitySolutionUI:threat_intelligence\" | \"securitySolutionUI:timelines\" | \"securitySolutionUI:timelines-templates\" | \"securitySolutionUI:trusted_apps\" | \"securitySolutionUI:users-all\" | \"securitySolutionUI:users-anomalies\" | \"securitySolutionUI:users-authentications\" | \"securitySolutionUI:users-events\" | \"securitySolutionUI:users-risk\" | \"securitySolutionUI:entity_analytics\" | \"securitySolutionUI:entity_analytics-management\" | \"securitySolutionUI:entity_analytics-asset-classification\" | \"securitySolutionUI:entity_analytics-entity_store_management\" | \"securitySolutionUI:coverage-overview\" | \"fleet:settings\" | \"fleet:agents\" | \"fleet:policies\" | \"fleet:data_streams\" | \"fleet:enrollment_tokens\" | \"fleet:uninstall_tokens\"" ], "path": "packages/core/chrome/core-chrome-browser/src/project_navigation.ts", "deprecated": false, diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index fae17c4d20213..8032ac6405445 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: 2024-11-10 +date: 2024-11-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 ab7f74db2545d..75e2407cd10ac 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: 2024-11-10 +date: 2024-11-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 c34b4e1f533ca..a433a292166db 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: 2024-11-10 +date: 2024-11-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 009e5c702f757..c55f6aebf24e0 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: 2024-11-10 +date: 2024-11-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 db761838cf7fe..264a15c21f091 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: 2024-11-10 +date: 2024-11-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 756e0a0cba8c7..bc0608681fd2c 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: 2024-11-10 +date: 2024-11-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 03329ecd441e3..d737e6e6ca443 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: 2024-11-10 +date: 2024-11-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 27a840cef5d73..6ac8945bd5ed0 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: 2024-11-10 +date: 2024-11-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 843b9169cf8e3..c1b509be36d7a 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: 2024-11-10 +date: 2024-11-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 88b5997a4315f..58a80bf9bfa88 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: 2024-11-10 +date: 2024-11-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 95ef79887c8c9..2ae00993441dc 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: 2024-11-10 +date: 2024-11-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 54b8e9c5878db..9242b3fdfeab4 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: 2024-11-10 +date: 2024-11-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 5828e493045e7..0bf08b8931220 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: 2024-11-10 +date: 2024-11-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 db5e8657b9d26..1f739c5487f5f 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: 2024-11-10 +date: 2024-11-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 1f5ad1c886aed..a5cccdd0d5a02 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: 2024-11-10 +date: 2024-11-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 b663a8930a225..551be6ea02180 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: 2024-11-10 +date: 2024-11-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 b72b34521f002..9a65ae1e2c5b9 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: 2024-11-10 +date: 2024-11-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 d3b56e55ecbdc..4de0ca0c9cfbe 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: 2024-11-10 +date: 2024-11-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 1689c0c674626..80b3e3e26641d 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: 2024-11-10 +date: 2024-11-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 9ba038c0cbd37..b882e55e28682 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: 2024-11-10 +date: 2024-11-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 fe3e04f5f54c7..3c8ea9e8c4663 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: 2024-11-10 +date: 2024-11-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 7dc5ad0280dfd..84df80a37f93b 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: 2024-11-10 +date: 2024-11-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 551889a02bcbb..f50ca818415f6 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: 2024-11-10 +date: 2024-11-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 a47779bc7c152..c5826d2034756 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: 2024-11-10 +date: 2024-11-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 d9af01ee7a939..2f73e097f7c9c 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: 2024-11-10 +date: 2024-11-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 576eb544e002d..fa7781332cfaa 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: 2024-11-10 +date: 2024-11-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 cb7556a01493f..4c36b5581b46c 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: 2024-11-10 +date: 2024-11-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 a166c88361087..a0e64301bb793 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: 2024-11-10 +date: 2024-11-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 08a53fcefcfa3..6c9755570d2d5 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: 2024-11-10 +date: 2024-11-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 54ea0083dbbd5..127df174a3bca 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: 2024-11-10 +date: 2024-11-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 7721d2217fd65..30d224c196688 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: 2024-11-10 +date: 2024-11-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 14e70ec33c1eb..b9c20af8150dc 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: 2024-11-10 +date: 2024-11-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 d4030babd0cbe..d47ddada7166f 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: 2024-11-10 +date: 2024-11-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 038f106ae49fa..6ee19e86b582d 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: 2024-11-10 +date: 2024-11-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 7ce2e42f0f3a8..310c9bf7bd3ef 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: 2024-11-10 +date: 2024-11-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 267ab94c4500c..679920d6b3dbc 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: 2024-11-10 +date: 2024-11-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 c16e7f40af975..3e0bfcaa83047 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: 2024-11-10 +date: 2024-11-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_feature_flags_browser.mdx b/api_docs/kbn_core_feature_flags_browser.mdx index 78c5943840e67..793b33b79ab0e 100644 --- a/api_docs/kbn_core_feature_flags_browser.mdx +++ b/api_docs/kbn_core_feature_flags_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-browser title: "@kbn/core-feature-flags-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-browser plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-browser'] --- import kbnCoreFeatureFlagsBrowserObj from './kbn_core_feature_flags_browser.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_browser_internal.mdx b/api_docs/kbn_core_feature_flags_browser_internal.mdx index 85d2546f097ae..db78d3fe60e69 100644 --- a/api_docs/kbn_core_feature_flags_browser_internal.mdx +++ b/api_docs/kbn_core_feature_flags_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-browser-internal title: "@kbn/core-feature-flags-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-browser-internal plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-browser-internal'] --- import kbnCoreFeatureFlagsBrowserInternalObj from './kbn_core_feature_flags_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_browser_mocks.mdx b/api_docs/kbn_core_feature_flags_browser_mocks.mdx index cba51e77d5539..7d1fa5abe7686 100644 --- a/api_docs/kbn_core_feature_flags_browser_mocks.mdx +++ b/api_docs/kbn_core_feature_flags_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-browser-mocks title: "@kbn/core-feature-flags-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-browser-mocks plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-browser-mocks'] --- import kbnCoreFeatureFlagsBrowserMocksObj from './kbn_core_feature_flags_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_server.mdx b/api_docs/kbn_core_feature_flags_server.mdx index 698de8981409b..bbde0e51faadb 100644 --- a/api_docs/kbn_core_feature_flags_server.mdx +++ b/api_docs/kbn_core_feature_flags_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-server title: "@kbn/core-feature-flags-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-server'] --- import kbnCoreFeatureFlagsServerObj from './kbn_core_feature_flags_server.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_server_internal.mdx b/api_docs/kbn_core_feature_flags_server_internal.mdx index 24db35fafbf8d..a8258021ff782 100644 --- a/api_docs/kbn_core_feature_flags_server_internal.mdx +++ b/api_docs/kbn_core_feature_flags_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-server-internal title: "@kbn/core-feature-flags-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-server-internal plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-server-internal'] --- import kbnCoreFeatureFlagsServerInternalObj from './kbn_core_feature_flags_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_feature_flags_server_mocks.mdx b/api_docs/kbn_core_feature_flags_server_mocks.mdx index 841cf097df01c..e91372be66864 100644 --- a/api_docs/kbn_core_feature_flags_server_mocks.mdx +++ b/api_docs/kbn_core_feature_flags_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-feature-flags-server-mocks title: "@kbn/core-feature-flags-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-feature-flags-server-mocks plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-feature-flags-server-mocks'] --- import kbnCoreFeatureFlagsServerMocksObj from './kbn_core_feature_flags_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index dcfe391a99df8..db7d253044782 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: 2024-11-10 +date: 2024-11-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 00137d31416fb..10cbd80fa71e6 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: 2024-11-10 +date: 2024-11-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 97710cf69f5df..9e0719fd6226d 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: 2024-11-10 +date: 2024-11-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 41529e7adb136..f0cbb937bd0fc 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: 2024-11-10 +date: 2024-11-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 89ae18137a86c..22a6fb73a4aea 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: 2024-11-10 +date: 2024-11-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 cf823ed9de48a..555a50af31ce1 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: 2024-11-10 +date: 2024-11-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 d21471012ce06..a5a3777f62ce2 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: 2024-11-10 +date: 2024-11-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 57d2294508c0d..8a68b71510141 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: 2024-11-10 +date: 2024-11-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 a1f7b520243e0..1e3c7b50cb546 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: 2024-11-10 +date: 2024-11-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 806e97209a176..02094a11da015 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: 2024-11-10 +date: 2024-11-12 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 7dea6b9b51af6..4e72693fbcae2 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: 2024-11-10 +date: 2024-11-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 8be8df4eef115..8211b20d63c72 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -4881,6 +4881,10 @@ "plugin": "stackConnectors", "path": "x-pack/plugins/stack_connectors/server/routes/get_well_known_email_service.ts" }, + { + "plugin": "stackConnectors", + "path": "x-pack/plugins/stack_connectors/server/routes/get_inference_services.ts" + }, { "plugin": "upgradeAssistant", "path": "x-pack/plugins/upgrade_assistant/server/routes/reindex_indices/reindex_indices.ts" @@ -5309,6 +5313,10 @@ "plugin": "ruleRegistry", "path": "x-pack/plugins/rule_registry/server/routes/__mocks__/server.ts" }, + { + "plugin": "stackConnectors", + "path": "x-pack/plugins/stack_connectors/server/routes/get_inference_services.test.ts" + }, { "plugin": "stackConnectors", "path": "x-pack/plugins/stack_connectors/server/routes/get_well_known_email_service.test.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 22a55999b2b20..c383d3d6e1964 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_core_http_server_internal.mdx index 76a3b0ffeb787..83ee885d5b209 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 7e847684aadc7..a4b726599b132 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: 2024-11-10 +date: 2024-11-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 06174be7b93d2..05cc2952a4afc 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: 2024-11-10 +date: 2024-11-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 b5de2f82119bd..f1b51bcfa87a1 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: 2024-11-10 +date: 2024-11-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 1977c5e0a8be0..a65144f8ba302 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: 2024-11-10 +date: 2024-11-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 eee3c8da40f38..adc74ef1f06dc 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: 2024-11-10 +date: 2024-11-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 894797810843b..11894e83ad03a 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: 2024-11-10 +date: 2024-11-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 98f27e65cdc23..55bc934440b3b 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: 2024-11-10 +date: 2024-11-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 034c9ad3f48cd..54c00e630fb75 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: 2024-11-10 +date: 2024-11-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 a4f0dddf96a5f..63f3d37559beb 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index a0046c0797b3e..40bd1317d3c24 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: 2024-11-10 +date: 2024-11-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 f5fd4db35139b..b4ea8da0ef01d 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: 2024-11-10 +date: 2024-11-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 cc0d5956cd1fa..f3538ffa4dac0 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: 2024-11-10 +date: 2024-11-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 8aa59648d0797..2c2a6c5b177e1 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: 2024-11-10 +date: 2024-11-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 90380bb9c42a2..b452533735095 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: 2024-11-10 +date: 2024-11-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 3fc4d0fc36ded..1c3a7d408a4b8 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: 2024-11-10 +date: 2024-11-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 1d68b54f686af..834f1f36f6126 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: 2024-11-10 +date: 2024-11-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 5590e08233ca1..831056b508fc6 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: 2024-11-10 +date: 2024-11-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 da22edb8269c7..5d992ebf8c7e9 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: 2024-11-10 +date: 2024-11-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 7f768178d564f..288efd553f05b 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: 2024-11-10 +date: 2024-11-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 f411d12c497bc..236a8d2d7dde1 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: 2024-11-10 +date: 2024-11-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 0bc94373c6df8..dcbecaf76180b 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: 2024-11-10 +date: 2024-11-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 6dfbeac99e48f..594b3db1ef9d6 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: 2024-11-10 +date: 2024-11-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 2f12d246852d4..fa8a2e37ef0e0 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: 2024-11-10 +date: 2024-11-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 b51ef6731a04f..4d73bf4d98a2f 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: 2024-11-10 +date: 2024-11-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 412506323d4dc..012eda39beccd 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: 2024-11-10 +date: 2024-11-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 696aedd38ebf6..c7faa587a4df8 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: 2024-11-10 +date: 2024-11-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 a9f10d3f054b1..0a0c46759a1e1 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: 2024-11-10 +date: 2024-11-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 abc649756abaa..50e0d2ca27119 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: 2024-11-10 +date: 2024-11-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 5db989cb9a02e..a9b42a446f338 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: 2024-11-10 +date: 2024-11-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 da92f53770b46..037504f5764f2 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: 2024-11-10 +date: 2024-11-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 cd1254b8b4de4..29787d92e125f 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: 2024-11-10 +date: 2024-11-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 d84d540f812ac..47f2713f6ce27 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: 2024-11-10 +date: 2024-11-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 8fad40262e6a5..9a01acebf0229 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: 2024-11-10 +date: 2024-11-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 cc93c2408a190..ce9178e7537a7 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: 2024-11-10 +date: 2024-11-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 9d4d3224e6913..33bd5fa638783 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: 2024-11-10 +date: 2024-11-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_contracts_browser.mdx b/api_docs/kbn_core_plugins_contracts_browser.mdx index 91b3a204785df..7f60209675cdd 100644 --- a/api_docs/kbn_core_plugins_contracts_browser.mdx +++ b/api_docs/kbn_core_plugins_contracts_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-browser title: "@kbn/core-plugins-contracts-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-browser plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-browser'] --- import kbnCorePluginsContractsBrowserObj from './kbn_core_plugins_contracts_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_server.mdx b/api_docs/kbn_core_plugins_contracts_server.mdx index 828516d938845..56baf81f1aa17 100644 --- a/api_docs/kbn_core_plugins_contracts_server.mdx +++ b/api_docs/kbn_core_plugins_contracts_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-server title: "@kbn/core-plugins-contracts-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-server'] --- import kbnCorePluginsContractsServerObj from './kbn_core_plugins_contracts_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index b0ca1147804b4..508a9fdbbe398 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: 2024-11-10 +date: 2024-11-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 a7c367e63cd8a..957f6cb6ae9f3 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: 2024-11-10 +date: 2024-11-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 00979968dbfc2..6cb81ba1b176e 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: 2024-11-10 +date: 2024-11-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 3cf0037d7aa8c..e07fdc43eddc8 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: 2024-11-10 +date: 2024-11-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 2e226e422d9df..e03db8dd11d72 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: 2024-11-10 +date: 2024-11-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 b1ddfdbb2b39e..e0db4f9df4527 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: 2024-11-10 +date: 2024-11-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 da9c9329c82c1..2f9512345141d 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: 2024-11-10 +date: 2024-11-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 f6f429c22e458..bd5a474c975d9 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index f39127097422f..fd05514ecf0d1 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index 553e6ff180341..4e4f95947b23e 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: 2024-11-10 +date: 2024-11-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 519c91ca3ec60..5b4b09e5eb4b2 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: 2024-11-10 +date: 2024-11-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 456c43b2938fd..3789f0ffd14b1 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: 2024-11-10 +date: 2024-11-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 8b01f07d1f648..9f175b48961b6 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: 2024-11-10 +date: 2024-11-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 7419aa8865645..57993e1bf6062 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: 2024-11-10 +date: 2024-11-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 ad9815f9ab5f1..f49475ec5aaee 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 4cf04f0b1cb82..7de2c4c3eabe6 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 122e9c5027e88..911c0b4661aa9 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: 2024-11-10 +date: 2024-11-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 c4b6619397acd..65584cde18ee5 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: 2024-11-10 +date: 2024-11-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 9b7ceeb031649..7cb1ffe660311 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: 2024-11-10 +date: 2024-11-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 eed8fc80a82cf..6cbf30d3ea641 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: 2024-11-10 +date: 2024-11-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 7d9631a9a7ab4..805dbd672bd21 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 8430dd99548bb..2653391291952 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: 2024-11-10 +date: 2024-11-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 f24bb0ea72eaa..f842bc5c03f2b 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: 2024-11-10 +date: 2024-11-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 668c2b2816408..483ac1602b82a 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: 2024-11-10 +date: 2024-11-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 ff60605a55cf3..403a2a37c2899 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: 2024-11-10 +date: 2024-11-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_security_browser.mdx b/api_docs/kbn_core_security_browser.mdx index 69c3b72d20e45..0dcb447e8fee6 100644 --- a/api_docs/kbn_core_security_browser.mdx +++ b/api_docs/kbn_core_security_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser title: "@kbn/core-security-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser'] --- import kbnCoreSecurityBrowserObj from './kbn_core_security_browser.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser_internal.mdx b/api_docs/kbn_core_security_browser_internal.mdx index bc60bd1cb57c6..e55d560824692 100644 --- a/api_docs/kbn_core_security_browser_internal.mdx +++ b/api_docs/kbn_core_security_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser-internal title: "@kbn/core-security-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser-internal plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser-internal'] --- import kbnCoreSecurityBrowserInternalObj from './kbn_core_security_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser_mocks.mdx b/api_docs/kbn_core_security_browser_mocks.mdx index 4ecf160b14fa0..fd8915f08c0c7 100644 --- a/api_docs/kbn_core_security_browser_mocks.mdx +++ b/api_docs/kbn_core_security_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser-mocks title: "@kbn/core-security-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser-mocks plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser-mocks'] --- import kbnCoreSecurityBrowserMocksObj from './kbn_core_security_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_security_common.mdx b/api_docs/kbn_core_security_common.mdx index e1a555c9898fe..e8d59c0a1a20f 100644 --- a/api_docs/kbn_core_security_common.mdx +++ b/api_docs/kbn_core_security_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-common title: "@kbn/core-security-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-common'] --- import kbnCoreSecurityCommonObj from './kbn_core_security_common.devdocs.json'; diff --git a/api_docs/kbn_core_security_server.mdx b/api_docs/kbn_core_security_server.mdx index 177ab26c9f6d5..44f101b0964fd 100644 --- a/api_docs/kbn_core_security_server.mdx +++ b/api_docs/kbn_core_security_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server title: "@kbn/core-security-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server'] --- import kbnCoreSecurityServerObj from './kbn_core_security_server.devdocs.json'; diff --git a/api_docs/kbn_core_security_server_internal.mdx b/api_docs/kbn_core_security_server_internal.mdx index 95285462ec83c..5c61fb024f1b5 100644 --- a/api_docs/kbn_core_security_server_internal.mdx +++ b/api_docs/kbn_core_security_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server-internal title: "@kbn/core-security-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server-internal plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server-internal'] --- import kbnCoreSecurityServerInternalObj from './kbn_core_security_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_security_server_mocks.mdx b/api_docs/kbn_core_security_server_mocks.mdx index d3e9d7ee423f4..10fb8ff1e098e 100644 --- a/api_docs/kbn_core_security_server_mocks.mdx +++ b/api_docs/kbn_core_security_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server-mocks title: "@kbn/core-security-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server-mocks plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server-mocks'] --- import kbnCoreSecurityServerMocksObj from './kbn_core_security_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index dd50142759b71..5ae33f1587141 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: 2024-11-10 +date: 2024-11-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 d23544e689464..cef994182b972 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: 2024-11-10 +date: 2024-11-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 c353565cdc9e6..b2b2cb7b568f6 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: 2024-11-10 +date: 2024-11-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 c109afd8f6234..ef527c950cd30 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: 2024-11-10 +date: 2024-11-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 2bf3636a02e89..938f83007fbcf 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: 2024-11-10 +date: 2024-11-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 bb35ab5dbf02a..a50c3b1828d6e 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: 2024-11-10 +date: 2024-11-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 6f11e379373e6..6a4b625285f0a 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: 2024-11-10 +date: 2024-11-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 e741bb5e7e4cd..02c5352bd4d17 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: 2024-11-10 +date: 2024-11-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_model_versions.mdx b/api_docs/kbn_core_test_helpers_model_versions.mdx index b207e9f64712c..8aaf6a5f2adf5 100644 --- a/api_docs/kbn_core_test_helpers_model_versions.mdx +++ b/api_docs/kbn_core_test_helpers_model_versions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-model-versions title: "@kbn/core-test-helpers-model-versions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-model-versions plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-model-versions'] --- import kbnCoreTestHelpersModelVersionsObj from './kbn_core_test_helpers_model_versions.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 b0cdeaf2f00e8..6aa9349a03527 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: 2024-11-10 +date: 2024-11-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 7e279df6cc60b..87b2f6d5c9396 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: 2024-11-10 +date: 2024-11-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 fc6ad7b2c8869..32ecd45349e11 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: 2024-11-10 +date: 2024-11-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_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 6e0ff959d7450..4cbeda7788db9 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: 2024-11-10 +date: 2024-11-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 1fb29c6c899aa..d953b935075ef 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: 2024-11-10 +date: 2024-11-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 fa2bce7f6cbde..fff46b5326d0d 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: 2024-11-10 +date: 2024-11-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 e2b7e33a64ecb..53cf35bd07a40 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: 2024-11-10 +date: 2024-11-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 a0369dfa5c1cb..d038ab88a60af 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: 2024-11-10 +date: 2024-11-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 0839550d97f61..b3a3706f59145 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: 2024-11-10 +date: 2024-11-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 3de68be7936fa..a2556a776c144 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: 2024-11-10 +date: 2024-11-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 48dec3594a8e8..f5e222efbd2b2 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: 2024-11-10 +date: 2024-11-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 cd16b7558abfc..a4f5b11d8bdb1 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: 2024-11-10 +date: 2024-11-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 845e1f0f224d8..54002865f12d3 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: 2024-11-10 +date: 2024-11-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 1500811c59061..9e0390f9284c0 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: 2024-11-10 +date: 2024-11-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_profile_browser.mdx b/api_docs/kbn_core_user_profile_browser.mdx index 50570ba053980..c46f4f10e0e5e 100644 --- a/api_docs/kbn_core_user_profile_browser.mdx +++ b/api_docs/kbn_core_user_profile_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser title: "@kbn/core-user-profile-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser'] --- import kbnCoreUserProfileBrowserObj from './kbn_core_user_profile_browser.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser_internal.mdx b/api_docs/kbn_core_user_profile_browser_internal.mdx index 86d77d447dd1d..f6e6a8b574207 100644 --- a/api_docs/kbn_core_user_profile_browser_internal.mdx +++ b/api_docs/kbn_core_user_profile_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser-internal title: "@kbn/core-user-profile-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser-internal plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser-internal'] --- import kbnCoreUserProfileBrowserInternalObj from './kbn_core_user_profile_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser_mocks.mdx b/api_docs/kbn_core_user_profile_browser_mocks.mdx index cb9207ae2bc8c..9d342ea1d8698 100644 --- a/api_docs/kbn_core_user_profile_browser_mocks.mdx +++ b/api_docs/kbn_core_user_profile_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser-mocks title: "@kbn/core-user-profile-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser-mocks plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser-mocks'] --- import kbnCoreUserProfileBrowserMocksObj from './kbn_core_user_profile_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_common.mdx b/api_docs/kbn_core_user_profile_common.mdx index bc81d9a28fd43..c86d118151f0d 100644 --- a/api_docs/kbn_core_user_profile_common.mdx +++ b/api_docs/kbn_core_user_profile_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-common title: "@kbn/core-user-profile-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-common'] --- import kbnCoreUserProfileCommonObj from './kbn_core_user_profile_common.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server.mdx b/api_docs/kbn_core_user_profile_server.mdx index bc877942ccac9..4e32a6961089c 100644 --- a/api_docs/kbn_core_user_profile_server.mdx +++ b/api_docs/kbn_core_user_profile_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server title: "@kbn/core-user-profile-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server'] --- import kbnCoreUserProfileServerObj from './kbn_core_user_profile_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server_internal.mdx b/api_docs/kbn_core_user_profile_server_internal.mdx index 720bc1b93fe6e..b2e719a02d6b5 100644 --- a/api_docs/kbn_core_user_profile_server_internal.mdx +++ b/api_docs/kbn_core_user_profile_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server-internal title: "@kbn/core-user-profile-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server-internal plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server-internal'] --- import kbnCoreUserProfileServerInternalObj from './kbn_core_user_profile_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server_mocks.mdx b/api_docs/kbn_core_user_profile_server_mocks.mdx index 6aa24c02eded8..44c3d2ffb3452 100644 --- a/api_docs/kbn_core_user_profile_server_mocks.mdx +++ b/api_docs/kbn_core_user_profile_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server-mocks title: "@kbn/core-user-profile-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server-mocks plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server-mocks'] --- import kbnCoreUserProfileServerMocksObj from './kbn_core_user_profile_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 5008643b50f55..88c82c120c85a 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: 2024-11-10 +date: 2024-11-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_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index d90dde244a34c..85949052d0c4a 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: 2024-11-10 +date: 2024-11-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 380f53922e177..46e178ce0b711 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: 2024-11-10 +date: 2024-11-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 bd37988bcb376..f118affa95cd0 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_custom_icons.mdx b/api_docs/kbn_custom_icons.mdx index 33f742426f3ed..e663abed4b7eb 100644 --- a/api_docs/kbn_custom_icons.mdx +++ b/api_docs/kbn_custom_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-icons title: "@kbn/custom-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-icons plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-icons'] --- import kbnCustomIconsObj from './kbn_custom_icons.devdocs.json'; diff --git a/api_docs/kbn_custom_integrations.mdx b/api_docs/kbn_custom_integrations.mdx index ca1d92e803ba3..c5bcf7da108b8 100644 --- a/api_docs/kbn_custom_integrations.mdx +++ b/api_docs/kbn_custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-integrations title: "@kbn/custom-integrations" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-integrations plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-integrations'] --- import kbnCustomIntegrationsObj from './kbn_custom_integrations.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 68d52f798093a..05a5dbabe2df5 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_forge.mdx b/api_docs/kbn_data_forge.mdx index 884c096c6f195..a8388fdda54c1 100644 --- a/api_docs/kbn_data_forge.mdx +++ b/api_docs/kbn_data_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-forge title: "@kbn/data-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-forge plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-forge'] --- import kbnDataForgeObj from './kbn_data_forge.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 06dbe09dee103..ab42e4e762238 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_data_stream_adapter.mdx b/api_docs/kbn_data_stream_adapter.mdx index 16e9c878c437f..d4e94e43d07e2 100644 --- a/api_docs/kbn_data_stream_adapter.mdx +++ b/api_docs/kbn_data_stream_adapter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-stream-adapter title: "@kbn/data-stream-adapter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-stream-adapter plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-stream-adapter'] --- import kbnDataStreamAdapterObj from './kbn_data_stream_adapter.devdocs.json'; diff --git a/api_docs/kbn_data_view_utils.mdx b/api_docs/kbn_data_view_utils.mdx index be2e38e98ea8f..44350ffee0018 100644 --- a/api_docs/kbn_data_view_utils.mdx +++ b/api_docs/kbn_data_view_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-view-utils title: "@kbn/data-view-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-view-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-view-utils'] --- import kbnDataViewUtilsObj from './kbn_data_view_utils.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index a7fd20e6ed966..53b25850f8df7 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: 2024-11-10 +date: 2024-11-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 83c60338d0c7e..9af32e7352b29 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: 2024-11-10 +date: 2024-11-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 e20555dbab9a3..7190eea79989f 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_fleet.mdx b/api_docs/kbn_deeplinks_fleet.mdx index 0986c2ee9c48f..9b6d2bef5fca2 100644 --- a/api_docs/kbn_deeplinks_fleet.mdx +++ b/api_docs/kbn_deeplinks_fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-fleet title: "@kbn/deeplinks-fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-fleet plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-fleet'] --- import kbnDeeplinksFleetObj from './kbn_deeplinks_fleet.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index f67b1d1beda2f..64a284f83f05d 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: 2024-11-10 +date: 2024-11-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 a77d9fcc9adeb..46c0550d1e336 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: 2024-11-10 +date: 2024-11-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 376e5e492d044..7dfd297037c53 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: 2024-11-10 +date: 2024-11-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.devdocs.json b/api_docs/kbn_deeplinks_search.devdocs.json index d8cd4e993a4e4..22c6f92587549 100644 --- a/api_docs/kbn_deeplinks_search.devdocs.json +++ b/api_docs/kbn_deeplinks_search.devdocs.json @@ -30,7 +30,7 @@ "label": "DeepLinkId", "description": [], "signature": [ - "\"appSearch\" | \"enterpriseSearch\" | \"enterpriseSearchContent\" | \"enterpriseSearchApplications\" | \"searchInferenceEndpoints\" | \"enterpriseSearchAnalytics\" | \"workplaceSearch\" | \"serverlessElasticsearch\" | \"serverlessConnectors\" | \"searchPlayground\" | \"searchHomepage\" | \"enterpriseSearchContent:connectors\" | \"enterpriseSearchContent:searchIndices\" | \"enterpriseSearchContent:webCrawlers\" | \"enterpriseSearchApplications:searchApplications\" | \"enterpriseSearchApplications:playground\" | \"appSearch:engines\" | \"searchInferenceEndpoints:inferenceEndpoints\" | \"elasticsearchStart\" | \"elasticsearchIndices\" | \"enterpriseSearchElasticsearch\" | \"enterpriseSearchVectorSearch\" | \"enterpriseSearchSemanticSearch\" | \"enterpriseSearchAISearch\"" + "\"appSearch\" | \"enterpriseSearch\" | \"enterpriseSearchContent\" | \"enterpriseSearchApplications\" | \"searchInferenceEndpoints\" | \"enterpriseSearchAnalytics\" | \"workplaceSearch\" | \"serverlessElasticsearch\" | \"serverlessConnectors\" | \"searchPlayground\" | \"searchHomepage\" | \"enterpriseSearchContent:connectors\" | \"enterpriseSearchContent:searchIndices\" | \"enterpriseSearchContent:webCrawlers\" | \"enterpriseSearchApplications:searchApplications\" | \"enterpriseSearchApplications:playground\" | \"appSearch:engines\" | \"searchInferenceEndpoints:inferenceEndpoints\" | \"elasticsearchStart\" | \"elasticsearchIndices\" | \"enterpriseSearchElasticsearch\" | \"enterpriseSearchVectorSearch\" | \"enterpriseSearchSemanticSearch\" | \"enterpriseSearchAISearch\" | \"elasticsearchIndices:createIndex\"" ], "path": "packages/deeplinks/search/deep_links.ts", "deprecated": false, diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index 5f20b9959df1a..595d9fe34f8da 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_security.mdx b/api_docs/kbn_deeplinks_security.mdx index 06c29487c0aca..c8972591f99c2 100644 --- a/api_docs/kbn_deeplinks_security.mdx +++ b/api_docs/kbn_deeplinks_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-security title: "@kbn/deeplinks-security" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-security plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-security'] --- import kbnDeeplinksSecurityObj from './kbn_deeplinks_security.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_shared.mdx b/api_docs/kbn_deeplinks_shared.mdx index d4a64d6bb2a2e..3aaefdeed692e 100644 --- a/api_docs/kbn_deeplinks_shared.mdx +++ b/api_docs/kbn_deeplinks_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-shared title: "@kbn/deeplinks-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-shared plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-shared'] --- import kbnDeeplinksSharedObj from './kbn_deeplinks_shared.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index cb8fcf5ec07fb..3ec8e4ffe178c 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: 2024-11-10 +date: 2024-11-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 18eecf2d4bcce..938aac32af481 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: 2024-11-10 +date: 2024-11-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 1135b89985cbb..6a1a579bcc4e2 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: 2024-11-10 +date: 2024-11-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 c1ddebf012dd8..d68d42a1fbc39 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: 2024-11-10 +date: 2024-11-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 893a968e13a5e..864f684cd5d69 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: 2024-11-10 +date: 2024-11-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 d116d9639ea1f..2f83a9993ece7 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: 2024-11-10 +date: 2024-11-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 a5a03e485dad7..dbf2659bfd26f 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: 2024-11-10 +date: 2024-11-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 126248514b123..99b18514c257c 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_contextual_components.devdocs.json b/api_docs/kbn_discover_contextual_components.devdocs.json index b987fc4267420..cd6c2ab526e25 100644 --- a/api_docs/kbn_discover_contextual_components.devdocs.json +++ b/api_docs/kbn_discover_contextual_components.devdocs.json @@ -174,9 +174,9 @@ "ExplainExplanation", " | undefined; highlight?: Record | undefined; inner_hits?: Record | undefined; matched_queries?: string[] | undefined; _nested?: ", + "> | undefined; matched_queries?: string[] | Record | undefined; _nested?: ", "SearchNestedIdentity", - " | undefined; _ignored?: string[] | undefined; ignored_field_values?: Record | undefined; _shard?: string | undefined; _node?: string | undefined; _routing?: string | undefined; _rank?: number | undefined; _seq_no?: number | undefined; _primary_term?: number | undefined; _version?: number | undefined; }; id: string; isAnchor?: boolean | undefined; }" + " | undefined; _ignored?: string[] | undefined; ignored_field_values?: Record | undefined; _shard?: string | undefined; _node?: string | undefined; _routing?: string | undefined; _rank?: number | undefined; _seq_no?: number | undefined; _primary_term?: number | undefined; _version?: number | undefined; }; id: string; isAnchor?: boolean | undefined; }" ], "path": "packages/kbn-discover-contextual-components/src/data_types/logs/components/summary_column/utils.tsx", "deprecated": false, diff --git a/api_docs/kbn_discover_contextual_components.mdx b/api_docs/kbn_discover_contextual_components.mdx index f90b6f8985636..68e6317d384e2 100644 --- a/api_docs/kbn_discover_contextual_components.mdx +++ b/api_docs/kbn_discover_contextual_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-contextual-components title: "@kbn/discover-contextual-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-contextual-components plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-contextual-components'] --- import kbnDiscoverContextualComponentsObj from './kbn_discover_contextual_components.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index bf4f841400e20..ec4e0bd3901b7 100644 --- a/api_docs/kbn_discover_utils.mdx +++ b/api_docs/kbn_discover_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-utils title: "@kbn/discover-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 850c4a18ee39f..0ef234ad26dcb 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: 2024-11-10 +date: 2024-11-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 2702f69156938..100e0358119ec 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_dom_drag_drop.mdx index 089448654b158..50724896d794e 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: 2024-11-10 +date: 2024-11-12 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 f31719fe91b92..60105e01565f4 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 996db7dec146d..2a958b1dc9ac6 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: 2024-11-10 +date: 2024-11-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_agent_utils.mdx b/api_docs/kbn_elastic_agent_utils.mdx index dda2e2030e569..b9658cbf5597f 100644 --- a/api_docs/kbn_elastic_agent_utils.mdx +++ b/api_docs/kbn_elastic_agent_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-agent-utils title: "@kbn/elastic-agent-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-agent-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-agent-utils'] --- import kbnElasticAgentUtilsObj from './kbn_elastic_agent_utils.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index ef12d33ed1a75..81b029f25b45a 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant_common.mdx b/api_docs/kbn_elastic_assistant_common.mdx index a21a8df0dfa58..1bd5f4dc78524 100644 --- a/api_docs/kbn_elastic_assistant_common.mdx +++ b/api_docs/kbn_elastic_assistant_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant-common title: "@kbn/elastic-assistant-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_entities_schema.mdx b/api_docs/kbn_entities_schema.mdx index 21636d8849446..a1cae02d138d2 100644 --- a/api_docs/kbn_entities_schema.mdx +++ b/api_docs/kbn_entities_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-entities-schema title: "@kbn/entities-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/entities-schema plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/entities-schema'] --- import kbnEntitiesSchemaObj from './kbn_entities_schema.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index ebd77a91caaad..167bbfa298fda 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: 2024-11-10 +date: 2024-11-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 e408bd32ffd34..2df4b2919483c 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: 2024-11-10 +date: 2024-11-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 a0cbfffe7bc90..8cba7dad7d059 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: 2024-11-10 +date: 2024-11-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 b4037d794893c..7e3765672afdb 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: 2024-11-10 +date: 2024-11-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.devdocs.json b/api_docs/kbn_es_types.devdocs.json index d9baac147e267..60ef30c14df1c 100644 --- a/api_docs/kbn_es_types.devdocs.json +++ b/api_docs/kbn_es_types.devdocs.json @@ -493,6 +493,8 @@ "AggregationsRateAggregation", "; reverse_nested: ", "AggregationsReverseNestedAggregation", + "; random_sampler: ", + "AggregationsRandomSamplerAggregation", "; sampler: ", "AggregationsSamplerAggregation", "; scripted_metric: ", @@ -515,6 +517,8 @@ "AggregationsSumBucketAggregation", "; terms: ", "AggregationsTermsAggregation", + "; time_series: ", + "AggregationsTimeSeriesAggregation", "; top_hits: ", "AggregationsTopHitsAggregation", "; t_test: ", diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 010294f3687c3..3008d09049256 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: 2024-11-10 +date: 2024-11-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 2ca9fb754a86f..9ad9028b3f58c 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: 2024-11-10 +date: 2024-11-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_esql_ast.mdx b/api_docs/kbn_esql_ast.mdx index 868d111d0832f..c1ec125936856 100644 --- a/api_docs/kbn_esql_ast.mdx +++ b/api_docs/kbn_esql_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-ast title: "@kbn/esql-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-ast plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-ast'] --- import kbnEsqlAstObj from './kbn_esql_ast.devdocs.json'; diff --git a/api_docs/kbn_esql_editor.mdx b/api_docs/kbn_esql_editor.mdx index d93d65c75fbe5..0623f45442967 100644 --- a/api_docs/kbn_esql_editor.mdx +++ b/api_docs/kbn_esql_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-editor title: "@kbn/esql-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-editor plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-editor'] --- import kbnEsqlEditorObj from './kbn_esql_editor.devdocs.json'; diff --git a/api_docs/kbn_esql_utils.mdx b/api_docs/kbn_esql_utils.mdx index 7eb695f3eb090..606cd098419e4 100644 --- a/api_docs/kbn_esql_utils.mdx +++ b/api_docs/kbn_esql_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-utils title: "@kbn/esql-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-utils'] --- import kbnEsqlUtilsObj from './kbn_esql_utils.devdocs.json'; diff --git a/api_docs/kbn_esql_validation_autocomplete.mdx b/api_docs/kbn_esql_validation_autocomplete.mdx index 9cb6536735f14..bdda8ed946225 100644 --- a/api_docs/kbn_esql_validation_autocomplete.mdx +++ b/api_docs/kbn_esql_validation_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-validation-autocomplete title: "@kbn/esql-validation-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-validation-autocomplete plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-validation-autocomplete'] --- import kbnEsqlValidationAutocompleteObj from './kbn_esql_validation_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index cf150d8584947..71ac2174e6918 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-common'] --- import kbnEventAnnotationCommonObj from './kbn_event_annotation_common.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_components.mdx b/api_docs/kbn_event_annotation_components.mdx index a6b94398890cc..ee224c8deeed9 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-components'] --- import kbnEventAnnotationComponentsObj from './kbn_event_annotation_components.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 489e50b25ec96..5431633de2453 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: 2024-11-10 +date: 2024-11-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 55f5c1ba26bcb..69e7372f4de5e 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_field_utils.mdx b/api_docs/kbn_field_utils.mdx index 59965cf55036b..a69e347028788 100644 --- a/api_docs/kbn_field_utils.mdx +++ b/api_docs/kbn_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-utils title: "@kbn/field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-utils'] --- import kbnFieldUtilsObj from './kbn_field_utils.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index aaa171be04879..dc8f6b7f3be16 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: 2024-11-10 +date: 2024-11-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_formatters.mdx b/api_docs/kbn_formatters.mdx index d0cd317591a25..36d81b43db66d 100644 --- a/api_docs/kbn_formatters.mdx +++ b/api_docs/kbn_formatters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-formatters title: "@kbn/formatters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/formatters plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/formatters'] --- import kbnFormattersObj from './kbn_formatters.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 7ca5d78746af0..a867f15a2ef95 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: 2024-11-10 +date: 2024-11-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_ftr_common_functional_ui_services.mdx b/api_docs/kbn_ftr_common_functional_ui_services.mdx index d7acef3d9f421..723193f3ff8cb 100644 --- a/api_docs/kbn_ftr_common_functional_ui_services.mdx +++ b/api_docs/kbn_ftr_common_functional_ui_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-ui-services title: "@kbn/ftr-common-functional-ui-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-ui-services plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-ui-services'] --- import kbnFtrCommonFunctionalUiServicesObj from './kbn_ftr_common_functional_ui_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 1113833946ce6..431e1754c3d84 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: 2024-11-10 +date: 2024-11-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 345cbfb15640b..735ec74e591ca 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: 2024-11-10 +date: 2024-11-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 dda4c0f14cc88..993d1c37ed4fe 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_grid_layout.mdx b/api_docs/kbn_grid_layout.mdx index ced780a7de485..57a3074656dc2 100644 --- a/api_docs/kbn_grid_layout.mdx +++ b/api_docs/kbn_grid_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-grid-layout title: "@kbn/grid-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/grid-layout plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/grid-layout'] --- import kbnGridLayoutObj from './kbn_grid_layout.devdocs.json'; diff --git a/api_docs/kbn_grouping.mdx b/api_docs/kbn_grouping.mdx index c734b583edd71..95cce0d41bab8 100644 --- a/api_docs/kbn_grouping.mdx +++ b/api_docs/kbn_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-grouping title: "@kbn/grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/grouping plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/grouping'] --- import kbnGroupingObj from './kbn_grouping.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 2d69201e6a3e9..567731d8779b5 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: 2024-11-10 +date: 2024-11-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 75f1a04ce809c..2124fcf4aed6a 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: 2024-11-10 +date: 2024-11-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 dbbd634346bce..320bed94d54a5 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: 2024-11-10 +date: 2024-11-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 cfc60f348ca78..1d262d68de226 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: 2024-11-10 +date: 2024-11-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 0dbf15092c990..a706989eea5a6 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: 2024-11-10 +date: 2024-11-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 19368ad58deac..26fe80f6e1c7a 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: 2024-11-10 +date: 2024-11-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 94eb34e6c2848..f4ce63cdc4391 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: 2024-11-10 +date: 2024-11-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 b771ec600f314..8b7f563d8da94 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: 2024-11-10 +date: 2024-11-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 2a131f248499e..c776e26e543b7 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_index_lifecycle_management_common_shared.devdocs.json b/api_docs/kbn_index_lifecycle_management_common_shared.devdocs.json new file mode 100644 index 0000000000000..62664293d6a46 --- /dev/null +++ b/api_docs/kbn_index_lifecycle_management_common_shared.devdocs.json @@ -0,0 +1,1447 @@ +{ + "id": "@kbn/index-lifecycle-management-common-shared", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.AllocateAction", + "type": "Interface", + "tags": [], + "label": "AllocateAction", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.AllocateAction.number_of_replicas", + "type": "number", + "tags": [], + "label": "number_of_replicas", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.AllocateAction.include", + "type": "Object", + "tags": [], + "label": "include", + "description": [], + "signature": [ + "{} | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.AllocateAction.exclude", + "type": "Object", + "tags": [], + "label": "exclude", + "description": [], + "signature": [ + "{} | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.AllocateAction.require", + "type": "Object", + "tags": [], + "label": "require", + "description": [], + "signature": [ + "{ [attribute: string]: string; } | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.CommonPhaseSettings", + "type": "Interface", + "tags": [], + "label": "CommonPhaseSettings", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.CommonPhaseSettings.phaseEnabled", + "type": "boolean", + "tags": [], + "label": "phaseEnabled", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.DeletePhase", + "type": "Interface", + "tags": [], + "label": "DeletePhase", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.DeletePhase", + "text": "DeletePhase" + }, + " extends ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.CommonPhaseSettings", + "text": "CommonPhaseSettings" + }, + ",", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.PhaseWithMinAge", + "text": "PhaseWithMinAge" + } + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.DeletePhase.waitForSnapshotPolicy", + "type": "string", + "tags": [], + "label": "waitForSnapshotPolicy", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.DownsampleAction", + "type": "Interface", + "tags": [], + "label": "DownsampleAction", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.DownsampleAction.fixed_interval", + "type": "string", + "tags": [], + "label": "fixed_interval", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.ForcemergeAction", + "type": "Interface", + "tags": [], + "label": "ForcemergeAction", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.ForcemergeAction.max_num_segments", + "type": "number", + "tags": [], + "label": "max_num_segments", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.ForcemergeAction.index_codec", + "type": "string", + "tags": [], + "label": "index_codec", + "description": [], + "signature": [ + "\"best_compression\" | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.MigrateAction", + "type": "Interface", + "tags": [], + "label": "MigrateAction", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.MigrateAction.enabled", + "type": "boolean", + "tags": [], + "label": "enabled", + "description": [ + "\nIf enabled is ever set it will probably only be set to `false` because the default value\nfor this is `true`. Rather leave unspecified for true when serialising." + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.Phases", + "type": "Interface", + "tags": [], + "label": "Phases", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.Phases.hot", + "type": "Object", + "tags": [], + "label": "hot", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedHotPhase", + "text": "SerializedHotPhase" + }, + " | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.Phases.warm", + "type": "Object", + "tags": [], + "label": "warm", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedWarmPhase", + "text": "SerializedWarmPhase" + }, + " | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.Phases.cold", + "type": "Object", + "tags": [], + "label": "cold", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedColdPhase", + "text": "SerializedColdPhase" + }, + " | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.Phases.frozen", + "type": "Object", + "tags": [], + "label": "frozen", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedFrozenPhase", + "text": "SerializedFrozenPhase" + }, + " | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.Phases.delete", + "type": "Object", + "tags": [], + "label": "delete", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedDeletePhase", + "text": "SerializedDeletePhase" + }, + " | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PhaseWithMinAge", + "type": "Interface", + "tags": [], + "label": "PhaseWithMinAge", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PhaseWithMinAge.selectedMinimumAge", + "type": "string", + "tags": [], + "label": "selectedMinimumAge", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PhaseWithMinAge.selectedMinimumAgeUnits", + "type": "string", + "tags": [], + "label": "selectedMinimumAgeUnits", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PolicyFromES", + "type": "Interface", + "tags": [], + "label": "PolicyFromES", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PolicyFromES.modifiedDate", + "type": "string", + "tags": [], + "label": "modifiedDate", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PolicyFromES.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PolicyFromES.policy", + "type": "Object", + "tags": [], + "label": "policy", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedPolicy", + "text": "SerializedPolicy" + } + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PolicyFromES.version", + "type": "number", + "tags": [], + "label": "version", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PolicyFromES.indices", + "type": "Array", + "tags": [], + "label": "indices", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PolicyFromES.dataStreams", + "type": "Array", + "tags": [], + "label": "dataStreams", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PolicyFromES.indexTemplates", + "type": "Array", + "tags": [], + "label": "indexTemplates", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.RolloverAction", + "type": "Interface", + "tags": [], + "label": "RolloverAction", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.RolloverAction.max_age", + "type": "string", + "tags": [], + "label": "max_age", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.RolloverAction.max_docs", + "type": "number", + "tags": [], + "label": "max_docs", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.RolloverAction.max_primary_shard_size", + "type": "string", + "tags": [], + "label": "max_primary_shard_size", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.RolloverAction.max_primary_shard_docs", + "type": "number", + "tags": [], + "label": "max_primary_shard_docs", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.RolloverAction.max_size", + "type": "string", + "tags": [ + "deprecated" + ], + "label": "max_size", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": true, + "trackAdoption": false, + "references": [ + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/__jest__/mocks.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/serializer/serializer.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_flyout/components/rollover.tsx" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_flyout/components/rollover.tsx" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/constants.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/constants.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/constants.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/constants.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer_and_serializer.test.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer_and_serializer.test.ts" + }, + { + "plugin": "indexLifecycleManagement", + "path": "x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/form/deserializer_and_serializer.test.ts" + } + ] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SearchableSnapshotAction", + "type": "Interface", + "tags": [], + "label": "SearchableSnapshotAction", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SearchableSnapshotAction.snapshot_repository", + "type": "string", + "tags": [], + "label": "snapshot_repository", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SearchableSnapshotAction.force_merge_index", + "type": "CompoundType", + "tags": [], + "label": "force_merge_index", + "description": [ + "\nWe do not configure this value in the UI as it is an advanced setting that will\nnot suit the vast majority of cases." + ], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedActionWithAllocation", + "type": "Interface", + "tags": [], + "label": "SerializedActionWithAllocation", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedActionWithAllocation.allocate", + "type": "Object", + "tags": [], + "label": "allocate", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.AllocateAction", + "text": "AllocateAction" + }, + " | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedActionWithAllocation.migrate", + "type": "Object", + "tags": [], + "label": "migrate", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.MigrateAction", + "text": "MigrateAction" + }, + " | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedColdPhase", + "type": "Interface", + "tags": [], + "label": "SerializedColdPhase", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedColdPhase", + "text": "SerializedColdPhase" + }, + " extends ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedPhase", + "text": "SerializedPhase" + } + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedColdPhase.actions", + "type": "Object", + "tags": [], + "label": "actions", + "description": [], + "signature": [ + "{ freeze?: {} | undefined; readonly?: {} | undefined; downsample?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.DownsampleAction", + "text": "DownsampleAction" + }, + " | undefined; allocate?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.AllocateAction", + "text": "AllocateAction" + }, + " | undefined; set_priority?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SetPriorityAction", + "text": "SetPriorityAction" + }, + " | undefined; migrate?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.MigrateAction", + "text": "MigrateAction" + }, + " | undefined; searchable_snapshot?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SearchableSnapshotAction", + "text": "SearchableSnapshotAction" + }, + " | undefined; }" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedDeletePhase", + "type": "Interface", + "tags": [], + "label": "SerializedDeletePhase", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedDeletePhase", + "text": "SerializedDeletePhase" + }, + " extends ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedPhase", + "text": "SerializedPhase" + } + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedDeletePhase.actions", + "type": "Object", + "tags": [], + "label": "actions", + "description": [], + "signature": [ + "{ wait_for_snapshot?: { policy: string; } | undefined; delete?: { delete_searchable_snapshot?: boolean | undefined; } | undefined; }" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedFrozenPhase", + "type": "Interface", + "tags": [], + "label": "SerializedFrozenPhase", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedFrozenPhase", + "text": "SerializedFrozenPhase" + }, + " extends ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedPhase", + "text": "SerializedPhase" + } + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedFrozenPhase.actions", + "type": "Object", + "tags": [], + "label": "actions", + "description": [], + "signature": [ + "{ searchable_snapshot?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SearchableSnapshotAction", + "text": "SearchableSnapshotAction" + }, + " | undefined; }" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedHotPhase", + "type": "Interface", + "tags": [], + "label": "SerializedHotPhase", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedHotPhase", + "text": "SerializedHotPhase" + }, + " extends ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedPhase", + "text": "SerializedPhase" + } + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedHotPhase.actions", + "type": "Object", + "tags": [], + "label": "actions", + "description": [], + "signature": [ + "{ rollover?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.RolloverAction", + "text": "RolloverAction" + }, + " | undefined; forcemerge?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.ForcemergeAction", + "text": "ForcemergeAction" + }, + " | undefined; readonly?: {} | undefined; shrink?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.ShrinkAction", + "text": "ShrinkAction" + }, + " | undefined; downsample?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.DownsampleAction", + "text": "DownsampleAction" + }, + " | undefined; set_priority?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SetPriorityAction", + "text": "SetPriorityAction" + }, + " | undefined; searchable_snapshot?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SearchableSnapshotAction", + "text": "SearchableSnapshotAction" + }, + " | undefined; }" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedPhase", + "type": "Interface", + "tags": [], + "label": "SerializedPhase", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedPhase.min_age", + "type": "string", + "tags": [], + "label": "min_age", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedPhase.actions", + "type": "Object", + "tags": [], + "label": "actions", + "description": [], + "signature": [ + "{ [action: string]: any; }" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedPolicy", + "type": "Interface", + "tags": [], + "label": "SerializedPolicy", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedPolicy.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedPolicy.phases", + "type": "Object", + "tags": [], + "label": "phases", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.Phases", + "text": "Phases" + } + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedPolicy.deprecated", + "type": "CompoundType", + "tags": [], + "label": "deprecated", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedPolicy._meta", + "type": "Object", + "tags": [], + "label": "_meta", + "description": [], + "signature": [ + "Record | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedWarmPhase", + "type": "Interface", + "tags": [], + "label": "SerializedWarmPhase", + "description": [], + "signature": [ + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedWarmPhase", + "text": "SerializedWarmPhase" + }, + " extends ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SerializedPhase", + "text": "SerializedPhase" + } + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SerializedWarmPhase.actions", + "type": "Object", + "tags": [], + "label": "actions", + "description": [], + "signature": [ + "{ allocate?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.AllocateAction", + "text": "AllocateAction" + }, + " | undefined; shrink?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.ShrinkAction", + "text": "ShrinkAction" + }, + " | undefined; forcemerge?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.ForcemergeAction", + "text": "ForcemergeAction" + }, + " | undefined; readonly?: {} | undefined; downsample?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.DownsampleAction", + "text": "DownsampleAction" + }, + " | undefined; set_priority?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.SetPriorityAction", + "text": "SetPriorityAction" + }, + " | undefined; migrate?: ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.MigrateAction", + "text": "MigrateAction" + }, + " | undefined; }" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SetPriorityAction", + "type": "Interface", + "tags": [], + "label": "SetPriorityAction", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.SetPriorityAction.priority", + "type": "CompoundType", + "tags": [], + "label": "priority", + "description": [], + "signature": [ + "number | null" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.ShrinkAction", + "type": "Interface", + "tags": [], + "label": "ShrinkAction", + "description": [], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.ShrinkAction.number_of_shards", + "type": "number", + "tags": [], + "label": "number_of_shards", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.ShrinkAction.max_primary_shard_size", + "type": "string", + "tags": [], + "label": "max_primary_shard_size", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.ShrinkAction.allow_write_after_shrink", + "type": "CompoundType", + "tags": [], + "label": "allow_write_after_shrink", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.ILM_LOCATOR_ID", + "type": "string", + "tags": [], + "label": "ILM_LOCATOR_ID", + "description": [], + "signature": [ + "\"ILM_LOCATOR_ID\"" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.Phase", + "type": "Type", + "tags": [], + "label": "Phase", + "description": [], + "signature": [ + "keyof ", + { + "pluginId": "@kbn/index-lifecycle-management-common-shared", + "scope": "common", + "docId": "kibKbnIndexLifecycleManagementCommonSharedPluginApi", + "section": "def-common.Phases", + "text": "Phases" + } + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PhaseExceptDelete", + "type": "Type", + "tags": [], + "label": "PhaseExceptDelete", + "description": [], + "signature": [ + "\"warm\" | \"hot\" | \"frozen\" | \"cold\"" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PhaseWithAllocation", + "type": "Type", + "tags": [], + "label": "PhaseWithAllocation", + "description": [], + "signature": [ + "\"warm\" | \"cold\"" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PhaseWithDownsample", + "type": "Type", + "tags": [], + "label": "PhaseWithDownsample", + "description": [], + "signature": [ + "\"warm\" | \"hot\" | \"cold\"" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/index-lifecycle-management-common-shared", + "id": "def-common.PhaseWithTiming", + "type": "Type", + "tags": [], + "label": "PhaseWithTiming", + "description": [], + "signature": [ + "\"delete\" | \"warm\" | \"frozen\" | \"cold\"" + ], + "path": "x-pack/packages/index-lifecycle-management/index_lifecycle_management_common_shared/src/policies.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_index_lifecycle_management_common_shared.mdx b/api_docs/kbn_index_lifecycle_management_common_shared.mdx new file mode 100644 index 0000000000000..0ed700c24a6e7 --- /dev/null +++ b/api_docs/kbn_index_lifecycle_management_common_shared.mdx @@ -0,0 +1,33 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnIndexLifecycleManagementCommonSharedPluginApi +slug: /kibana-dev-docs/api/kbn-index-lifecycle-management-common-shared +title: "@kbn/index-lifecycle-management-common-shared" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/index-lifecycle-management-common-shared plugin +date: 2024-11-12 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/index-lifecycle-management-common-shared'] +--- +import kbnIndexLifecycleManagementCommonSharedObj from './kbn_index_lifecycle_management_common_shared.devdocs.json'; + + + +Contact [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 75 | 0 | 73 | 0 | + +## Common + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_index_management_shared_types.mdx b/api_docs/kbn_index_management_shared_types.mdx index 9aa8c3d4a8525..8c28979c41e4a 100644 --- a/api_docs/kbn_index_management_shared_types.mdx +++ b/api_docs/kbn_index_management_shared_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-index-management-shared-types title: "@kbn/index-management-shared-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/index-management-shared-types plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/index-management-shared-types'] --- import kbnIndexManagementSharedTypesObj from './kbn_index_management_shared_types.devdocs.json'; diff --git a/api_docs/kbn_inference_common.mdx b/api_docs/kbn_inference_common.mdx index 5707b0dee8442..8724d9451e1da 100644 --- a/api_docs/kbn_inference_common.mdx +++ b/api_docs/kbn_inference_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-inference-common title: "@kbn/inference-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/inference-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/inference-common'] --- import kbnInferenceCommonObj from './kbn_inference_common.devdocs.json'; diff --git a/api_docs/kbn_inference_integration_flyout.mdx b/api_docs/kbn_inference_integration_flyout.mdx index 13f101fde9b1c..a8e658592606a 100644 --- a/api_docs/kbn_inference_integration_flyout.mdx +++ b/api_docs/kbn_inference_integration_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-inference_integration_flyout title: "@kbn/inference_integration_flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/inference_integration_flyout plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/inference_integration_flyout'] --- import kbnInferenceIntegrationFlyoutObj from './kbn_inference_integration_flyout.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 4c34cfd001046..ff578001a59f5 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: 2024-11-10 +date: 2024-11-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 29c5511b68be6..7a1f6e64c1750 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_investigation_shared.mdx b/api_docs/kbn_investigation_shared.mdx index 2fa7a18034560..a1dd7ecaaf2be 100644 --- a/api_docs/kbn_investigation_shared.mdx +++ b/api_docs/kbn_investigation_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-investigation-shared title: "@kbn/investigation-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/investigation-shared plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/investigation-shared'] --- import kbnInvestigationSharedObj from './kbn_investigation_shared.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 3b613b0693a90..a104f3097eff9 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: 2024-11-10 +date: 2024-11-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_ipynb.mdx b/api_docs/kbn_ipynb.mdx index 3009daa0e2c87..2b496ce99a8a9 100644 --- a/api_docs/kbn_ipynb.mdx +++ b/api_docs/kbn_ipynb.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ipynb title: "@kbn/ipynb" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ipynb plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ipynb'] --- import kbnIpynbObj from './kbn_ipynb.devdocs.json'; diff --git a/api_docs/kbn_item_buffer.mdx b/api_docs/kbn_item_buffer.mdx index 1b3675bc8b84e..38d654ba2bb8a 100644 --- a/api_docs/kbn_item_buffer.mdx +++ b/api_docs/kbn_item_buffer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-item-buffer title: "@kbn/item-buffer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/item-buffer plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/item-buffer'] --- import kbnItemBufferObj from './kbn_item_buffer.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index a1cdf973c4c26..c2fec834962d7 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: 2024-11-10 +date: 2024-11-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 a42099416fc08..d213ff07e87fd 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: 2024-11-10 +date: 2024-11-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 f380f815b2340..3fe23883d8cb7 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_json_schemas.mdx b/api_docs/kbn_json_schemas.mdx index 600f8bee812ee..3a94e136d53e0 100644 --- a/api_docs/kbn_json_schemas.mdx +++ b/api_docs/kbn_json_schemas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-schemas title: "@kbn/json-schemas" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-schemas plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-schemas'] --- import kbnJsonSchemasObj from './kbn_json_schemas.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index dd2c54b529e61..9d4377358e123 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_language_documentation.mdx index 92295b77760e7..85764d5c9825b 100644 --- a/api_docs/kbn_language_documentation.mdx +++ b/api_docs/kbn_language_documentation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation title: "@kbn/language-documentation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation'] --- import kbnLanguageDocumentationObj from './kbn_language_documentation.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index 700581c1f4cc8..535c118c9dec2 100644 --- a/api_docs/kbn_lens_embeddable_utils.mdx +++ b/api_docs/kbn_lens_embeddable_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-embeddable-utils title: "@kbn/lens-embeddable-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-embeddable-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-embeddable-utils'] --- import kbnLensEmbeddableUtilsObj from './kbn_lens_embeddable_utils.devdocs.json'; diff --git a/api_docs/kbn_lens_formula_docs.mdx b/api_docs/kbn_lens_formula_docs.mdx index 95e4bc76d5fbb..1069244918736 100644 --- a/api_docs/kbn_lens_formula_docs.mdx +++ b/api_docs/kbn_lens_formula_docs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-formula-docs title: "@kbn/lens-formula-docs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-formula-docs plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-formula-docs'] --- import kbnLensFormulaDocsObj from './kbn_lens_formula_docs.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 5e4e4d8296515..c3154b703fedc 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: 2024-11-10 +date: 2024-11-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 be0f183a82854..e6be28e24ce45 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_content_badge.mdx b/api_docs/kbn_managed_content_badge.mdx index 96dda426347fe..2e6ffa89d0043 100644 --- a/api_docs/kbn_managed_content_badge.mdx +++ b/api_docs/kbn_managed_content_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-content-badge title: "@kbn/managed-content-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-content-badge plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-content-badge'] --- import kbnManagedContentBadgeObj from './kbn_managed_content_badge.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index eeb5d66bd9c71..f152444c1f62a 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: 2024-11-10 +date: 2024-11-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 eb86ef98a7ca9..69e712b46815b 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: 2024-11-10 +date: 2024-11-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_settings_application.mdx b/api_docs/kbn_management_settings_application.mdx index 65e8bbcbc1c3e..16e99fc5cc94e 100644 --- a/api_docs/kbn_management_settings_application.mdx +++ b/api_docs/kbn_management_settings_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-application title: "@kbn/management-settings-application" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-application plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-application'] --- import kbnManagementSettingsApplicationObj from './kbn_management_settings_application.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_category.mdx b/api_docs/kbn_management_settings_components_field_category.mdx index 0d9916e3ee079..a00641e9efbc4 100644 --- a/api_docs/kbn_management_settings_components_field_category.mdx +++ b/api_docs/kbn_management_settings_components_field_category.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-category title: "@kbn/management-settings-components-field-category" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-category plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-category'] --- import kbnManagementSettingsComponentsFieldCategoryObj from './kbn_management_settings_components_field_category.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_input.mdx b/api_docs/kbn_management_settings_components_field_input.mdx index 6f8aeed4cc3f2..b071cbc096936 100644 --- a/api_docs/kbn_management_settings_components_field_input.mdx +++ b/api_docs/kbn_management_settings_components_field_input.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-input title: "@kbn/management-settings-components-field-input" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-input plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-input'] --- import kbnManagementSettingsComponentsFieldInputObj from './kbn_management_settings_components_field_input.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_row.mdx b/api_docs/kbn_management_settings_components_field_row.mdx index 82e8285889844..f79d711ca5216 100644 --- a/api_docs/kbn_management_settings_components_field_row.mdx +++ b/api_docs/kbn_management_settings_components_field_row.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-row title: "@kbn/management-settings-components-field-row" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-row plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-row'] --- import kbnManagementSettingsComponentsFieldRowObj from './kbn_management_settings_components_field_row.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_form.mdx b/api_docs/kbn_management_settings_components_form.mdx index 618aca65de9da..de54101e88d05 100644 --- a/api_docs/kbn_management_settings_components_form.mdx +++ b/api_docs/kbn_management_settings_components_form.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-form title: "@kbn/management-settings-components-form" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-form plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-form'] --- import kbnManagementSettingsComponentsFormObj from './kbn_management_settings_components_form.devdocs.json'; diff --git a/api_docs/kbn_management_settings_field_definition.mdx b/api_docs/kbn_management_settings_field_definition.mdx index 9d566f9a6c0f3..940d0042bfc8d 100644 --- a/api_docs/kbn_management_settings_field_definition.mdx +++ b/api_docs/kbn_management_settings_field_definition.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-field-definition title: "@kbn/management-settings-field-definition" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-field-definition plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-field-definition'] --- import kbnManagementSettingsFieldDefinitionObj from './kbn_management_settings_field_definition.devdocs.json'; diff --git a/api_docs/kbn_management_settings_ids.devdocs.json b/api_docs/kbn_management_settings_ids.devdocs.json index 19accbeb0d254..bc654d267378b 100644 --- a/api_docs/kbn_management_settings_ids.devdocs.json +++ b/api_docs/kbn_management_settings_ids.devdocs.json @@ -907,21 +907,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "@kbn/management-settings-ids", - "id": "def-common.METRICS_ALLOW_CHECKING_FOR_FAILED_SHARDS_ID", - "type": "string", - "tags": [], - "label": "METRICS_ALLOW_CHECKING_FOR_FAILED_SHARDS_ID", - "description": [], - "signature": [ - "\"metrics:allowCheckingForFailedShards\"" - ], - "path": "packages/kbn-management/settings/setting_ids/index.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "@kbn/management-settings-ids", "id": "def-common.METRICS_ALLOW_STRING_INDICES_ID", diff --git a/api_docs/kbn_management_settings_ids.mdx b/api_docs/kbn_management_settings_ids.mdx index 6b89f67b5a37a..0a46cd7571288 100644 --- a/api_docs/kbn_management_settings_ids.mdx +++ b/api_docs/kbn_management_settings_ids.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-ids title: "@kbn/management-settings-ids" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-ids plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux @elastic/kibana-management](https://github.com/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 140 | 0 | 139 | 0 | +| 139 | 0 | 138 | 0 | ## Common diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index 2ca4f14bea68e..c4dba23025fd7 100644 --- a/api_docs/kbn_management_settings_section_registry.mdx +++ b/api_docs/kbn_management_settings_section_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-section-registry title: "@kbn/management-settings-section-registry" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-section-registry plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-section-registry'] --- import kbnManagementSettingsSectionRegistryObj from './kbn_management_settings_section_registry.devdocs.json'; diff --git a/api_docs/kbn_management_settings_types.mdx b/api_docs/kbn_management_settings_types.mdx index 6b7f0081a1f7c..b52d09baa28e1 100644 --- a/api_docs/kbn_management_settings_types.mdx +++ b/api_docs/kbn_management_settings_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-types title: "@kbn/management-settings-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-types plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-types'] --- import kbnManagementSettingsTypesObj from './kbn_management_settings_types.devdocs.json'; diff --git a/api_docs/kbn_management_settings_utilities.mdx b/api_docs/kbn_management_settings_utilities.mdx index 3476906b14250..03d44b1828809 100644 --- a/api_docs/kbn_management_settings_utilities.mdx +++ b/api_docs/kbn_management_settings_utilities.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-utilities title: "@kbn/management-settings-utilities" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-utilities plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-utilities'] --- import kbnManagementSettingsUtilitiesObj from './kbn_management_settings_utilities.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index 41476ad4398ee..a001d12638f02 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: 2024-11-10 +date: 2024-11-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_manifest.mdx b/api_docs/kbn_manifest.mdx index a0eb170086dbd..8fd4aea6ac226 100644 --- a/api_docs/kbn_manifest.mdx +++ b/api_docs/kbn_manifest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-manifest title: "@kbn/manifest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/manifest plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/manifest'] --- import kbnManifestObj from './kbn_manifest.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 51cb11fcebb64..b0b5c6273ea94 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: 2024-11-10 +date: 2024-11-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 abf3bda5f933f..2cc52ca631c68 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: 2024-11-10 +date: 2024-11-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 2348dac81da6e..7dcf7843651ca 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: 2024-11-10 +date: 2024-11-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 45877286f45e9..49bcc89d3d99e 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: 2024-11-10 +date: 2024-11-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_cancellable_search.mdx b/api_docs/kbn_ml_cancellable_search.mdx index f87deb92a7ea3..a4d9b5a984f39 100644 --- a/api_docs/kbn_ml_cancellable_search.mdx +++ b/api_docs/kbn_ml_cancellable_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-cancellable-search title: "@kbn/ml-cancellable-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-cancellable-search plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-cancellable-search'] --- import kbnMlCancellableSearchObj from './kbn_ml_cancellable_search.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index b2c17e20cb38b..a79a0aeaf53ef 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_chi2test.mdx b/api_docs/kbn_ml_chi2test.mdx index 859294aec3e90..ff3a6ba6c48a4 100644 --- a/api_docs/kbn_ml_chi2test.mdx +++ b/api_docs/kbn_ml_chi2test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-chi2test title: "@kbn/ml-chi2test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-chi2test plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-chi2test'] --- import kbnMlChi2testObj from './kbn_ml_chi2test.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 e3855f3b44236..4c3f4b54e4640 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: 2024-11-10 +date: 2024-11-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 8fe36e7583714..fddb315a8919a 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: 2024-11-10 +date: 2024-11-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 54c5002e3eac3..dbb7cc6c40ccf 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: 2024-11-10 +date: 2024-11-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 a36e4dda743f6..7d6c510e34203 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: 2024-11-10 +date: 2024-11-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 5c17c51d194e9..14cfe80893adb 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: 2024-11-10 +date: 2024-11-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_field_stats_flyout.mdx b/api_docs/kbn_ml_field_stats_flyout.mdx index 27e6e30a9dbdd..7d5b991fac89d 100644 --- a/api_docs/kbn_ml_field_stats_flyout.mdx +++ b/api_docs/kbn_ml_field_stats_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-field-stats-flyout title: "@kbn/ml-field-stats-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-field-stats-flyout plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-field-stats-flyout'] --- import kbnMlFieldStatsFlyoutObj from './kbn_ml_field_stats_flyout.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index fa41e6be54536..adf618a7bc189 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-in-memory-table'] --- import kbnMlInMemoryTableObj from './kbn_ml_in_memory_table.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index e403884bf0fae..b9a5f9259d431 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: 2024-11-10 +date: 2024-11-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 4d28ea44b7a7d..88020badbad19 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: 2024-11-10 +date: 2024-11-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 4676703ad7e34..db9949aeef209 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: 2024-11-10 +date: 2024-11-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 c70ef91f797da..4986f6e22610c 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: 2024-11-10 +date: 2024-11-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 a063f835e52fb..7bebcbd389657 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: 2024-11-10 +date: 2024-11-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 115f6ce86b6fa..ffc7decec804e 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: 2024-11-10 +date: 2024-11-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_parse_interval.mdx b/api_docs/kbn_ml_parse_interval.mdx index c4d670af31647..5c276242db361 100644 --- a/api_docs/kbn_ml_parse_interval.mdx +++ b/api_docs/kbn_ml_parse_interval.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-parse-interval title: "@kbn/ml-parse-interval" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-parse-interval plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-parse-interval'] --- import kbnMlParseIntervalObj from './kbn_ml_parse_interval.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index dce4ae2c19199..9a1bab0cc2bb6 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: 2024-11-10 +date: 2024-11-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 0a2654df0647a..aafa96694cab7 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: 2024-11-10 +date: 2024-11-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 2ad95a7ce8857..b07f25d73fce4 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: 2024-11-10 +date: 2024-11-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 c8412a0ff7d21..63076aa68f7e3 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: 2024-11-10 +date: 2024-11-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 65c696631c066..596110c694684 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: 2024-11-10 +date: 2024-11-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_time_buckets.mdx b/api_docs/kbn_ml_time_buckets.mdx index ca2251874675c..77d3e0cdb27de 100644 --- a/api_docs/kbn_ml_time_buckets.mdx +++ b/api_docs/kbn_ml_time_buckets.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-time-buckets title: "@kbn/ml-time-buckets" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-time-buckets plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-time-buckets'] --- import kbnMlTimeBucketsObj from './kbn_ml_time_buckets.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index b623fde614418..60724e72677bf 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: 2024-11-10 +date: 2024-11-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_ui_actions.mdx b/api_docs/kbn_ml_ui_actions.mdx index dc039d3c17adc..343401b698cfc 100644 --- a/api_docs/kbn_ml_ui_actions.mdx +++ b/api_docs/kbn_ml_ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-ui-actions title: "@kbn/ml-ui-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-ui-actions plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-ui-actions'] --- import kbnMlUiActionsObj from './kbn_ml_ui_actions.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 047116e2ef62a..6df0063365e7d 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: 2024-11-10 +date: 2024-11-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_ml_validators.mdx b/api_docs/kbn_ml_validators.mdx index c9b832bf5c5cf..23e597e2f0f43 100644 --- a/api_docs/kbn_ml_validators.mdx +++ b/api_docs/kbn_ml_validators.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-validators title: "@kbn/ml-validators" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-validators plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-validators'] --- import kbnMlValidatorsObj from './kbn_ml_validators.devdocs.json'; diff --git a/api_docs/kbn_mock_idp_utils.mdx b/api_docs/kbn_mock_idp_utils.mdx index a1b6a19e3d1fc..742d202cbcee7 100644 --- a/api_docs/kbn_mock_idp_utils.mdx +++ b/api_docs/kbn_mock_idp_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mock-idp-utils title: "@kbn/mock-idp-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mock-idp-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mock-idp-utils'] --- import kbnMockIdpUtilsObj from './kbn_mock_idp_utils.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 8f6716ec252af..a96e583d94e9f 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: 2024-11-10 +date: 2024-11-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 2d9431bbfc379..1defebd09d228 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_object_versioning_utils.mdx b/api_docs/kbn_object_versioning_utils.mdx index 5aed21660e2c0..8a81cb4f518ae 100644 --- a/api_docs/kbn_object_versioning_utils.mdx +++ b/api_docs/kbn_object_versioning_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning-utils title: "@kbn/object-versioning-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning-utils'] --- import kbnObjectVersioningUtilsObj from './kbn_object_versioning_utils.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 5fa338f1213fc..24b2d0f27bbdc 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: 2024-11-10 +date: 2024-11-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_observability_alerting_rule_utils.mdx b/api_docs/kbn_observability_alerting_rule_utils.mdx index 223b5a4d86259..c6067a685e93d 100644 --- a/api_docs/kbn_observability_alerting_rule_utils.mdx +++ b/api_docs/kbn_observability_alerting_rule_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-rule-utils title: "@kbn/observability-alerting-rule-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-rule-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-rule-utils'] --- import kbnObservabilityAlertingRuleUtilsObj from './kbn_observability_alerting_rule_utils.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index 350c62a551288..5ad4d6d3f3602 100644 --- a/api_docs/kbn_observability_alerting_test_data.mdx +++ b/api_docs/kbn_observability_alerting_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-test-data title: "@kbn/observability-alerting-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-test-data plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-test-data'] --- import kbnObservabilityAlertingTestDataObj from './kbn_observability_alerting_test_data.devdocs.json'; diff --git a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx index 72ea156722bdb..d8207d81dc261 100644 --- a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx +++ b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-get-padded-alert-time-range-util title: "@kbn/observability-get-padded-alert-time-range-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-get-padded-alert-time-range-util plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-get-padded-alert-time-range-util'] --- import kbnObservabilityGetPaddedAlertTimeRangeUtilObj from './kbn_observability_get_padded_alert_time_range_util.devdocs.json'; diff --git a/api_docs/kbn_observability_logs_overview.mdx b/api_docs/kbn_observability_logs_overview.mdx index 38990a1868558..58a812061ea3b 100644 --- a/api_docs/kbn_observability_logs_overview.mdx +++ b/api_docs/kbn_observability_logs_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-logs-overview title: "@kbn/observability-logs-overview" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-logs-overview plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-logs-overview'] --- import kbnObservabilityLogsOverviewObj from './kbn_observability_logs_overview.devdocs.json'; diff --git a/api_docs/kbn_observability_synthetics_test_data.mdx b/api_docs/kbn_observability_synthetics_test_data.mdx index b6dca99b53968..b10096eabf86f 100644 --- a/api_docs/kbn_observability_synthetics_test_data.mdx +++ b/api_docs/kbn_observability_synthetics_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-synthetics-test-data title: "@kbn/observability-synthetics-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-synthetics-test-data plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-synthetics-test-data'] --- import kbnObservabilitySyntheticsTestDataObj from './kbn_observability_synthetics_test_data.devdocs.json'; diff --git a/api_docs/kbn_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index ff2270f6e779a..e24dad4ac4c38 100644 --- a/api_docs/kbn_openapi_bundler.mdx +++ b/api_docs/kbn_openapi_bundler.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-bundler title: "@kbn/openapi-bundler" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-bundler plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-bundler'] --- import kbnOpenapiBundlerObj from './kbn_openapi_bundler.devdocs.json'; diff --git a/api_docs/kbn_openapi_generator.mdx b/api_docs/kbn_openapi_generator.mdx index 0edcc4cae2722..bdb4b573a9f80 100644 --- a/api_docs/kbn_openapi_generator.mdx +++ b/api_docs/kbn_openapi_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-generator title: "@kbn/openapi-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-generator plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-generator'] --- import kbnOpenapiGeneratorObj from './kbn_openapi_generator.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 360f7ff6bf65a..928955cf42b7e 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: 2024-11-10 +date: 2024-11-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 c3add8441c5b3..b973e2fc28702 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: 2024-11-10 +date: 2024-11-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 d86d4a80de8a2..b365a12c78ac1 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: 2024-11-10 +date: 2024-11-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_panel_loader.mdx b/api_docs/kbn_panel_loader.mdx index d31b70779d540..e762e03721710 100644 --- a/api_docs/kbn_panel_loader.mdx +++ b/api_docs/kbn_panel_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-panel-loader title: "@kbn/panel-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/panel-loader plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/panel-loader'] --- import kbnPanelLoaderObj from './kbn_panel_loader.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 9dda16b63cfcc..3165245e2fb97 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: 2024-11-10 +date: 2024-11-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_check.mdx b/api_docs/kbn_plugin_check.mdx index 63dc2e06b8bfc..0ad957cfc5199 100644 --- a/api_docs/kbn_plugin_check.mdx +++ b/api_docs/kbn_plugin_check.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-check title: "@kbn/plugin-check" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-check plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-check'] --- import kbnPluginCheckObj from './kbn_plugin_check.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 423477a418778..996544ca50192 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: 2024-11-10 +date: 2024-11-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 b3d7eb05ce47b..a338af0b37863 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_presentation_containers.mdx b/api_docs/kbn_presentation_containers.mdx index 4549db49f0075..35c491dd3aa3c 100644 --- a/api_docs/kbn_presentation_containers.mdx +++ b/api_docs/kbn_presentation_containers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-containers title: "@kbn/presentation-containers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-containers plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-containers'] --- import kbnPresentationContainersObj from './kbn_presentation_containers.devdocs.json'; diff --git a/api_docs/kbn_presentation_publishing.mdx b/api_docs/kbn_presentation_publishing.mdx index 781ed0c621578..ea63d73b73206 100644 --- a/api_docs/kbn_presentation_publishing.mdx +++ b/api_docs/kbn_presentation_publishing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-publishing title: "@kbn/presentation-publishing" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-publishing plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-publishing'] --- import kbnPresentationPublishingObj from './kbn_presentation_publishing.devdocs.json'; diff --git a/api_docs/kbn_product_doc_artifact_builder.mdx b/api_docs/kbn_product_doc_artifact_builder.mdx index a68423c371d85..e737c606ba67d 100644 --- a/api_docs/kbn_product_doc_artifact_builder.mdx +++ b/api_docs/kbn_product_doc_artifact_builder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-product-doc-artifact-builder title: "@kbn/product-doc-artifact-builder" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/product-doc-artifact-builder plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/product-doc-artifact-builder'] --- import kbnProductDocArtifactBuilderObj from './kbn_product_doc_artifact_builder.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index e1f113d529676..2461ac60f5b90 100644 --- a/api_docs/kbn_profiling_utils.mdx +++ b/api_docs/kbn_profiling_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-profiling-utils title: "@kbn/profiling-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/profiling-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/profiling-utils'] --- import kbnProfilingUtilsObj from './kbn_profiling_utils.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 1ad575c0449ee..278a1b53b11ea 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: 2024-11-10 +date: 2024-11-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 f0dd611a892b7..6cc9939a14c10 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_hooks.mdx b/api_docs/kbn_react_hooks.mdx index 730027b674986..d0a86fc48bdaf 100644 --- a/api_docs/kbn_react_hooks.mdx +++ b/api_docs/kbn_react_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-hooks title: "@kbn/react-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-hooks plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-hooks'] --- import kbnReactHooksObj from './kbn_react_hooks.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 8ca4d214864ed..fafac45b43fac 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-common'] --- import kbnReactKibanaContextCommonObj from './kbn_react_kibana_context_common.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_render.mdx b/api_docs/kbn_react_kibana_context_render.mdx index 8e1e56347556f..268d249666adb 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-render'] --- import kbnReactKibanaContextRenderObj from './kbn_react_kibana_context_render.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_root.mdx b/api_docs/kbn_react_kibana_context_root.mdx index 84a34d96fd9c2..89408f64335ad 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-root'] --- import kbnReactKibanaContextRootObj from './kbn_react_kibana_context_root.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_styled.mdx b/api_docs/kbn_react_kibana_context_styled.mdx index fadebde226580..642c0f510d32a 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-styled'] --- import kbnReactKibanaContextStyledObj from './kbn_react_kibana_context_styled.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_theme.mdx b/api_docs/kbn_react_kibana_context_theme.mdx index 872075cc85af9..6d69b3e1feb57 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-theme'] --- import kbnReactKibanaContextThemeObj from './kbn_react_kibana_context_theme.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_mount.mdx b/api_docs/kbn_react_kibana_mount.mdx index 81c398d0953a1..23d49b1d84a83 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_recently_accessed.mdx b/api_docs/kbn_recently_accessed.mdx index 8b82861786b7b..fb70861bf5c8e 100644 --- a/api_docs/kbn_recently_accessed.mdx +++ b/api_docs/kbn_recently_accessed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-recently-accessed title: "@kbn/recently-accessed" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/recently-accessed plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/recently-accessed'] --- import kbnRecentlyAccessedObj from './kbn_recently_accessed.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 1a9bc978e8815..c3e6209fe0cba 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: 2024-11-10 +date: 2024-11-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 6219e64230810..0a344992f3673 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: 2024-11-10 +date: 2024-11-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 fce761ca608db..d4593bb69ec11 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: 2024-11-10 +date: 2024-11-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 7c92964419f52..4bc026939319e 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: 2024-11-10 +date: 2024-11-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 b7cbf6c07aa13..495a620eed089 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_csv_share_panel.mdx b/api_docs/kbn_reporting_csv_share_panel.mdx index 79367332f7383..fcdbcff994406 100644 --- a/api_docs/kbn_reporting_csv_share_panel.mdx +++ b/api_docs/kbn_reporting_csv_share_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-csv-share-panel title: "@kbn/reporting-csv-share-panel" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-csv-share-panel plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-csv-share-panel'] --- import kbnReportingCsvSharePanelObj from './kbn_reporting_csv_share_panel.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index fd7d81062dd9d..bd9f21e11dc53 100644 --- a/api_docs/kbn_reporting_export_types_csv.mdx +++ b/api_docs/kbn_reporting_export_types_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv title: "@kbn/reporting-export-types-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv'] --- import kbnReportingExportTypesCsvObj from './kbn_reporting_export_types_csv.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv_common.mdx b/api_docs/kbn_reporting_export_types_csv_common.mdx index 6f0e90696c23b..a733ea5344aab 100644 --- a/api_docs/kbn_reporting_export_types_csv_common.mdx +++ b/api_docs/kbn_reporting_export_types_csv_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv-common title: "@kbn/reporting-export-types-csv-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv-common'] --- import kbnReportingExportTypesCsvCommonObj from './kbn_reporting_export_types_csv_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf.mdx b/api_docs/kbn_reporting_export_types_pdf.mdx index bef27400e8f41..1511dd22eeb34 100644 --- a/api_docs/kbn_reporting_export_types_pdf.mdx +++ b/api_docs/kbn_reporting_export_types_pdf.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf title: "@kbn/reporting-export-types-pdf" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf'] --- import kbnReportingExportTypesPdfObj from './kbn_reporting_export_types_pdf.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf_common.mdx b/api_docs/kbn_reporting_export_types_pdf_common.mdx index 30ac0f42d5d80..bff1a6c5a2981 100644 --- a/api_docs/kbn_reporting_export_types_pdf_common.mdx +++ b/api_docs/kbn_reporting_export_types_pdf_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf-common title: "@kbn/reporting-export-types-pdf-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf-common'] --- import kbnReportingExportTypesPdfCommonObj from './kbn_reporting_export_types_pdf_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png.mdx b/api_docs/kbn_reporting_export_types_png.mdx index 1f3f42f3bc2cb..d9948ebfb004b 100644 --- a/api_docs/kbn_reporting_export_types_png.mdx +++ b/api_docs/kbn_reporting_export_types_png.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png title: "@kbn/reporting-export-types-png" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png'] --- import kbnReportingExportTypesPngObj from './kbn_reporting_export_types_png.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png_common.mdx b/api_docs/kbn_reporting_export_types_png_common.mdx index 7a9509c2ab7d4..cc2af3e7afe08 100644 --- a/api_docs/kbn_reporting_export_types_png_common.mdx +++ b/api_docs/kbn_reporting_export_types_png_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png-common title: "@kbn/reporting-export-types-png-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png-common'] --- import kbnReportingExportTypesPngCommonObj from './kbn_reporting_export_types_png_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_mocks_server.mdx b/api_docs/kbn_reporting_mocks_server.mdx index c96ead9dc5381..823e66dde25cd 100644 --- a/api_docs/kbn_reporting_mocks_server.mdx +++ b/api_docs/kbn_reporting_mocks_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-mocks-server title: "@kbn/reporting-mocks-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-mocks-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-mocks-server'] --- import kbnReportingMocksServerObj from './kbn_reporting_mocks_server.devdocs.json'; diff --git a/api_docs/kbn_reporting_public.mdx b/api_docs/kbn_reporting_public.mdx index fc78ba5e5c054..adb3de1a0cdce 100644 --- a/api_docs/kbn_reporting_public.mdx +++ b/api_docs/kbn_reporting_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-public title: "@kbn/reporting-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-public plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-public'] --- import kbnReportingPublicObj from './kbn_reporting_public.devdocs.json'; diff --git a/api_docs/kbn_reporting_server.mdx b/api_docs/kbn_reporting_server.mdx index f1f62ca430eee..18dfc6adf3e47 100644 --- a/api_docs/kbn_reporting_server.mdx +++ b/api_docs/kbn_reporting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-server title: "@kbn/reporting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-server'] --- import kbnReportingServerObj from './kbn_reporting_server.devdocs.json'; diff --git a/api_docs/kbn_resizable_layout.mdx b/api_docs/kbn_resizable_layout.mdx index 44104bcc22961..d6fcf1550c508 100644 --- a/api_docs/kbn_resizable_layout.mdx +++ b/api_docs/kbn_resizable_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-resizable-layout title: "@kbn/resizable-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/resizable-layout plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_response_ops_feature_flag_service.mdx b/api_docs/kbn_response_ops_feature_flag_service.mdx index 2f8f1dbc0cad3..b22e6a15fe0e3 100644 --- a/api_docs/kbn_response_ops_feature_flag_service.mdx +++ b/api_docs/kbn_response_ops_feature_flag_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-response-ops-feature-flag-service title: "@kbn/response-ops-feature-flag-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/response-ops-feature-flag-service plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/response-ops-feature-flag-service'] --- import kbnResponseOpsFeatureFlagServiceObj from './kbn_response_ops_feature_flag_service.devdocs.json'; diff --git a/api_docs/kbn_response_ops_rule_params.mdx b/api_docs/kbn_response_ops_rule_params.mdx index f1c7ce801a53b..4d2c8f2bf2825 100644 --- a/api_docs/kbn_response_ops_rule_params.mdx +++ b/api_docs/kbn_response_ops_rule_params.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-response-ops-rule-params title: "@kbn/response-ops-rule-params" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/response-ops-rule-params plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/response-ops-rule-params'] --- import kbnResponseOpsRuleParamsObj from './kbn_response_ops_rule_params.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 736828e0ee660..a3f6b6cc34ccc 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rollup.mdx b/api_docs/kbn_rollup.mdx index 60768cf395264..f5b6092d25570 100644 --- a/api_docs/kbn_rollup.mdx +++ b/api_docs/kbn_rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rollup title: "@kbn/rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rollup plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rollup'] --- import kbnRollupObj from './kbn_rollup.devdocs.json'; diff --git a/api_docs/kbn_router_to_openapispec.mdx b/api_docs/kbn_router_to_openapispec.mdx index d9abbbb1bcd8e..fe7d8a3d6799a 100644 --- a/api_docs/kbn_router_to_openapispec.mdx +++ b/api_docs/kbn_router_to_openapispec.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-to-openapispec title: "@kbn/router-to-openapispec" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-to-openapispec plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-to-openapispec'] --- import kbnRouterToOpenapispecObj from './kbn_router_to_openapispec.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index 5c024727b2844..db74246897a4c 100644 --- a/api_docs/kbn_router_utils.mdx +++ b/api_docs/kbn_router_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-utils title: "@kbn/router-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-utils'] --- import kbnRouterUtilsObj from './kbn_router_utils.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 5fd7882fa443a..b7e99dcb1c428 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: 2024-11-10 +date: 2024-11-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 d77c4509bb9e7..7fad45ddc2667 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: 2024-11-10 +date: 2024-11-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 b3ecca674cab1..0171494294254 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: 2024-11-10 +date: 2024-11-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_screenshotting_server.mdx b/api_docs/kbn_screenshotting_server.mdx index 25d7ceed25db1..61e0f8fbcff1b 100644 --- a/api_docs/kbn_screenshotting_server.mdx +++ b/api_docs/kbn_screenshotting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-screenshotting-server title: "@kbn/screenshotting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/screenshotting-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/screenshotting-server'] --- import kbnScreenshottingServerObj from './kbn_screenshotting_server.devdocs.json'; diff --git a/api_docs/kbn_search_api_keys_components.mdx b/api_docs/kbn_search_api_keys_components.mdx index fa0b92053ae25..ed9420b3658c1 100644 --- a/api_docs/kbn_search_api_keys_components.mdx +++ b/api_docs/kbn_search_api_keys_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-keys-components title: "@kbn/search-api-keys-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-keys-components plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-keys-components'] --- import kbnSearchApiKeysComponentsObj from './kbn_search_api_keys_components.devdocs.json'; diff --git a/api_docs/kbn_search_api_keys_server.mdx b/api_docs/kbn_search_api_keys_server.mdx index e6ea55259b3f6..79819d9fc6fc8 100644 --- a/api_docs/kbn_search_api_keys_server.mdx +++ b/api_docs/kbn_search_api_keys_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-keys-server title: "@kbn/search-api-keys-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-keys-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-keys-server'] --- import kbnSearchApiKeysServerObj from './kbn_search_api_keys_server.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 337f147e31412..c5f4e270e01d1 100644 --- a/api_docs/kbn_search_api_panels.mdx +++ b/api_docs/kbn_search_api_panels.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-panels title: "@kbn/search-api-panels" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-panels plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index f49adeadd5fb2..1acdad3338824 100644 --- a/api_docs/kbn_search_connectors.mdx +++ b/api_docs/kbn_search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-connectors title: "@kbn/search-connectors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-connectors plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index 99cae73c4bc89..5c32759e084fe 100644 --- a/api_docs/kbn_search_errors.mdx +++ b/api_docs/kbn_search_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-errors title: "@kbn/search-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-errors plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-errors'] --- import kbnSearchErrorsObj from './kbn_search_errors.devdocs.json'; diff --git a/api_docs/kbn_search_index_documents.mdx b/api_docs/kbn_search_index_documents.mdx index 824741e454bde..1c2ca8ebe1217 100644 --- a/api_docs/kbn_search_index_documents.mdx +++ b/api_docs/kbn_search_index_documents.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-index-documents title: "@kbn/search-index-documents" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-index-documents plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-index-documents'] --- import kbnSearchIndexDocumentsObj from './kbn_search_index_documents.devdocs.json'; diff --git a/api_docs/kbn_search_response_warnings.mdx b/api_docs/kbn_search_response_warnings.mdx index c17d4290a9e6d..b783e3a2eaf03 100644 --- a/api_docs/kbn_search_response_warnings.mdx +++ b/api_docs/kbn_search_response_warnings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-response-warnings title: "@kbn/search-response-warnings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-response-warnings plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_search_shared_ui.mdx b/api_docs/kbn_search_shared_ui.mdx index 0baa230c38638..0b2b651652dc0 100644 --- a/api_docs/kbn_search_shared_ui.mdx +++ b/api_docs/kbn_search_shared_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-shared-ui title: "@kbn/search-shared-ui" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-shared-ui plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-shared-ui'] --- import kbnSearchSharedUiObj from './kbn_search_shared_ui.devdocs.json'; diff --git a/api_docs/kbn_search_types.mdx b/api_docs/kbn_search_types.mdx index 2621f48057e0c..248eb3a1df12b 100644 --- a/api_docs/kbn_search_types.mdx +++ b/api_docs/kbn_search_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-types title: "@kbn/search-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-types plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-types'] --- import kbnSearchTypesObj from './kbn_search_types.devdocs.json'; diff --git a/api_docs/kbn_security_api_key_management.mdx b/api_docs/kbn_security_api_key_management.mdx index a7488482ed485..dbb86b136acbf 100644 --- a/api_docs/kbn_security_api_key_management.mdx +++ b/api_docs/kbn_security_api_key_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-api-key-management title: "@kbn/security-api-key-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-api-key-management plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-api-key-management'] --- import kbnSecurityApiKeyManagementObj from './kbn_security_api_key_management.devdocs.json'; diff --git a/api_docs/kbn_security_authorization_core.mdx b/api_docs/kbn_security_authorization_core.mdx index 4567131c545a5..20e1cbf0e18ab 100644 --- a/api_docs/kbn_security_authorization_core.mdx +++ b/api_docs/kbn_security_authorization_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-authorization-core title: "@kbn/security-authorization-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-authorization-core plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-authorization-core'] --- import kbnSecurityAuthorizationCoreObj from './kbn_security_authorization_core.devdocs.json'; diff --git a/api_docs/kbn_security_authorization_core_common.mdx b/api_docs/kbn_security_authorization_core_common.mdx index e67ef3ac5326c..fe630c194a159 100644 --- a/api_docs/kbn_security_authorization_core_common.mdx +++ b/api_docs/kbn_security_authorization_core_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-authorization-core-common title: "@kbn/security-authorization-core-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-authorization-core-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-authorization-core-common'] --- import kbnSecurityAuthorizationCoreCommonObj from './kbn_security_authorization_core_common.devdocs.json'; diff --git a/api_docs/kbn_security_form_components.mdx b/api_docs/kbn_security_form_components.mdx index ca66db16c759a..0ed1baaaded6e 100644 --- a/api_docs/kbn_security_form_components.mdx +++ b/api_docs/kbn_security_form_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-form-components title: "@kbn/security-form-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-form-components plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-form-components'] --- import kbnSecurityFormComponentsObj from './kbn_security_form_components.devdocs.json'; diff --git a/api_docs/kbn_security_hardening.mdx b/api_docs/kbn_security_hardening.mdx index 3d67c31c267f4..84392a1922482 100644 --- a/api_docs/kbn_security_hardening.mdx +++ b/api_docs/kbn_security_hardening.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-hardening title: "@kbn/security-hardening" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-hardening plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-hardening'] --- import kbnSecurityHardeningObj from './kbn_security_hardening.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index 2c2a8b853318d..fd13c63ea575a 100644 --- a/api_docs/kbn_security_plugin_types_common.mdx +++ b/api_docs/kbn_security_plugin_types_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-common title: "@kbn/security-plugin-types-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-common plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-common'] --- import kbnSecurityPluginTypesCommonObj from './kbn_security_plugin_types_common.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_public.mdx b/api_docs/kbn_security_plugin_types_public.mdx index 122b4b8029a03..e7fdb4d05fd5e 100644 --- a/api_docs/kbn_security_plugin_types_public.mdx +++ b/api_docs/kbn_security_plugin_types_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-public title: "@kbn/security-plugin-types-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-public plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-public'] --- import kbnSecurityPluginTypesPublicObj from './kbn_security_plugin_types_public.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_server.mdx b/api_docs/kbn_security_plugin_types_server.mdx index 80da55ce1761c..206a5972bd9df 100644 --- a/api_docs/kbn_security_plugin_types_server.mdx +++ b/api_docs/kbn_security_plugin_types_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-server title: "@kbn/security-plugin-types-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-server'] --- import kbnSecurityPluginTypesServerObj from './kbn_security_plugin_types_server.devdocs.json'; diff --git a/api_docs/kbn_security_role_management_model.mdx b/api_docs/kbn_security_role_management_model.mdx index 2109360e0cdfa..0a310c07fb5d5 100644 --- a/api_docs/kbn_security_role_management_model.mdx +++ b/api_docs/kbn_security_role_management_model.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-role-management-model title: "@kbn/security-role-management-model" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-role-management-model plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-role-management-model'] --- import kbnSecurityRoleManagementModelObj from './kbn_security_role_management_model.devdocs.json'; diff --git a/api_docs/kbn_security_solution_distribution_bar.mdx b/api_docs/kbn_security_solution_distribution_bar.mdx index 88b8ec1de8d7e..ed1ff48e2f75f 100644 --- a/api_docs/kbn_security_solution_distribution_bar.mdx +++ b/api_docs/kbn_security_solution_distribution_bar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-distribution-bar title: "@kbn/security-solution-distribution-bar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-distribution-bar plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-distribution-bar'] --- import kbnSecuritySolutionDistributionBarObj from './kbn_security_solution_distribution_bar.devdocs.json'; diff --git a/api_docs/kbn_security_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 779a9911a08fa..0b1037a379453 100644 --- a/api_docs/kbn_security_solution_features.mdx +++ b/api_docs/kbn_security_solution_features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-features title: "@kbn/security-solution-features" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-features plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-features'] --- import kbnSecuritySolutionFeaturesObj from './kbn_security_solution_features.devdocs.json'; diff --git a/api_docs/kbn_security_solution_navigation.mdx b/api_docs/kbn_security_solution_navigation.mdx index cdcd95b0c3276..56252d485c862 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-navigation'] --- import kbnSecuritySolutionNavigationObj from './kbn_security_solution_navigation.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 76c56922c81c8..be7ebd0a51bed 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: 2024-11-10 +date: 2024-11-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 60e6a7d2000be..ab1043d3a23ee 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: 2024-11-10 +date: 2024-11-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_security_ui_components.mdx b/api_docs/kbn_security_ui_components.mdx index 37d4c192ec917..7fa49d6c162bc 100644 --- a/api_docs/kbn_security_ui_components.mdx +++ b/api_docs/kbn_security_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-ui-components title: "@kbn/security-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-ui-components plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-ui-components'] --- import kbnSecurityUiComponentsObj from './kbn_security_ui_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 533834a078201..3f42189484f91 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: 2024-11-10 +date: 2024-11-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 a5a76c2a621d9..e53c5eed42c89 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: 2024-11-10 +date: 2024-11-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 f9d9670bbfe13..cf035893cf017 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: 2024-11-10 +date: 2024-11-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 b096260aab33f..aad0fae8d8e16 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: 2024-11-10 +date: 2024-11-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 0e8043dad9776..5633cc6d7e029 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: 2024-11-10 +date: 2024-11-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_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 93a50d11b4c91..8f657380a69ac 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: 2024-11-10 +date: 2024-11-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 efa99b0f6f001..ec3f360c09e26 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: 2024-11-10 +date: 2024-11-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 35770f9043bec..2b217fc98c400 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: 2024-11-10 +date: 2024-11-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 34ad20adf6ee6..878a65839bfeb 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: 2024-11-10 +date: 2024-11-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 a25185f6695a4..ea0ff84683317 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: 2024-11-10 +date: 2024-11-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 cc960796a4748..0488ac71876c5 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: 2024-11-10 +date: 2024-11-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 cf4f6d047dd62..f7ad8bea1f46b 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: 2024-11-10 +date: 2024-11-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 38ae43c653dc6..0367555d973d1 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: 2024-11-10 +date: 2024-11-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 c68f97722f990..9d0cc192b6099 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: 2024-11-10 +date: 2024-11-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 aa0e2e5fcab6e..b240f2c990ec2 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: 2024-11-10 +date: 2024-11-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 cd7297ac80d4b..9be0aebca5bb4 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: 2024-11-10 +date: 2024-11-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 8beee33eb735d..d5283e51a4cc6 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: 2024-11-10 +date: 2024-11-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 1eff127b3a06b..b8ee887107519 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: 2024-11-10 +date: 2024-11-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 9df4eec1e987a..8ceead4e3a7f2 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: 2024-11-10 +date: 2024-11-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_server_route_repository_client.mdx b/api_docs/kbn_server_route_repository_client.mdx index d1bb9f0ad1f37..6dba800e4fdb8 100644 --- a/api_docs/kbn_server_route_repository_client.mdx +++ b/api_docs/kbn_server_route_repository_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository-client title: "@kbn/server-route-repository-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository-client plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository-client'] --- import kbnServerRouteRepositoryClientObj from './kbn_server_route_repository_client.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository_utils.mdx b/api_docs/kbn_server_route_repository_utils.mdx index 02de1d6184fa9..2196a4bc7b4c7 100644 --- a/api_docs/kbn_server_route_repository_utils.mdx +++ b/api_docs/kbn_server_route_repository_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository-utils title: "@kbn/server-route-repository-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository-utils'] --- import kbnServerRouteRepositoryUtilsObj from './kbn_server_route_repository_utils.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index 869fd4cd64baa..0c5fe48102b3e 100644 --- a/api_docs/kbn_serverless_common_settings.mdx +++ b/api_docs/kbn_serverless_common_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-common-settings title: "@kbn/serverless-common-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-common-settings plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-common-settings'] --- import kbnServerlessCommonSettingsObj from './kbn_serverless_common_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_observability_settings.mdx b/api_docs/kbn_serverless_observability_settings.mdx index 512562032c82b..c53bdd719a679 100644 --- a/api_docs/kbn_serverless_observability_settings.mdx +++ b/api_docs/kbn_serverless_observability_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-observability-settings title: "@kbn/serverless-observability-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-observability-settings plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-observability-settings'] --- import kbnServerlessObservabilitySettingsObj from './kbn_serverless_observability_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 48f452280e972..cb345cadee06f 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: 2024-11-10 +date: 2024-11-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_search_settings.mdx b/api_docs/kbn_serverless_search_settings.mdx index 787f084c3196a..a98951ad472d1 100644 --- a/api_docs/kbn_serverless_search_settings.mdx +++ b/api_docs/kbn_serverless_search_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-search-settings title: "@kbn/serverless-search-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-search-settings plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-search-settings'] --- import kbnServerlessSearchSettingsObj from './kbn_serverless_search_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_security_settings.mdx b/api_docs/kbn_serverless_security_settings.mdx index 7f3d632b93817..6277489025c9b 100644 --- a/api_docs/kbn_serverless_security_settings.mdx +++ b/api_docs/kbn_serverless_security_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-security-settings title: "@kbn/serverless-security-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-security-settings plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-security-settings'] --- import kbnServerlessSecuritySettingsObj from './kbn_serverless_security_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index dbc0c11908b83..d401be14dd287 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: 2024-11-10 +date: 2024-11-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 8d0d496464107..bc6f940e801ed 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: 2024-11-10 +date: 2024-11-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 a9f8d59e328c7..4df27618fc84c 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: 2024-11-10 +date: 2024-11-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_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index e8b7c6946e11d..52ac2d321f70c 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: 2024-11-10 +date: 2024-11-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_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 15a425bf79b6d..bcd7c251dc328 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: 2024-11-10 +date: 2024-11-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 961ddedb727c4..2d1a9fba09bcd 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: 2024-11-10 +date: 2024-11-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 a30c2e0f0e514..2e1eebaeeb407 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: 2024-11-10 +date: 2024-11-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 2ea435507db21..49efcf650726b 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: 2024-11-10 +date: 2024-11-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_error_boundary.mdx b/api_docs/kbn_shared_ux_error_boundary.mdx index 48f71a31cb288..4005ee46a345c 100644 --- a/api_docs/kbn_shared_ux_error_boundary.mdx +++ b/api_docs/kbn_shared_ux_error_boundary.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-error-boundary title: "@kbn/shared-ux-error-boundary" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-error-boundary plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-error-boundary'] --- import kbnSharedUxErrorBoundaryObj from './kbn_shared_ux_error_boundary.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 38845ac2c98f3..2eb3dd62aaab9 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: 2024-11-10 +date: 2024-11-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 4648f38b03626..7bc7d631581f6 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: 2024-11-10 +date: 2024-11-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 5c2de245d2a99..12ae3a987c046 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: 2024-11-10 +date: 2024-11-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 c3018601c7aa2..58741471353f1 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: 2024-11-10 +date: 2024-11-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 dabdaa1440d4f..e12e520c65aa9 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: 2024-11-10 +date: 2024-11-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 8361002df79e6..f594b69d93e59 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: 2024-11-10 +date: 2024-11-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 4b4d13d6babdf..69c62f3469c29 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: 2024-11-10 +date: 2024-11-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 6ca2bef2f70ec..fe4e8b4500579 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: 2024-11-10 +date: 2024-11-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 a594cb82773ef..5b9d0f3e97072 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: 2024-11-10 +date: 2024-11-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 9027ddd9d7070..366b13fad7000 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: 2024-11-10 +date: 2024-11-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 6db0d2a53d655..90438320f47b4 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: 2024-11-10 +date: 2024-11-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 622fc16626862..123431a8be248 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: 2024-11-10 +date: 2024-11-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 392a19c0ff2ba..d601c44e161ce 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: 2024-11-10 +date: 2024-11-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 3cd5fdd946c70..ce5b632cc677e 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: 2024-11-10 +date: 2024-11-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 36f53f7fb26bf..868bc47939dd8 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: 2024-11-10 +date: 2024-11-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 23584cbd75939..6a30f35b896a1 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: 2024-11-10 +date: 2024-11-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 78030bee3ea61..ae3ebda7ccc35 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: 2024-11-10 +date: 2024-11-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 816bd076e2f95..b08c2aeeb6b43 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: 2024-11-10 +date: 2024-11-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 aac92dca8e4ef..e7ad6701c0ec2 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: 2024-11-10 +date: 2024-11-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 14bf07e7285d0..3b530e1d35043 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: 2024-11-10 +date: 2024-11-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 c1f1afdfce475..9bde826c30867 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: 2024-11-10 +date: 2024-11-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 4a59f5fcb7e6e..6dae878b9b366 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: 2024-11-10 +date: 2024-11-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 61432bb1cb274..e7e40f4946999 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: 2024-11-10 +date: 2024-11-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 51df30ca370e8..7e8fb4207f484 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: 2024-11-10 +date: 2024-11-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 2e4d656d6cfa3..3c65e02bc8af9 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: 2024-11-10 +date: 2024-11-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 a2e464a5f3bce..3da736728a335 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: 2024-11-10 +date: 2024-11-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 737b8ee827601..13337242d1f92 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: 2024-11-10 +date: 2024-11-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 9e46c20d39e30..12fd4e5b08cff 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: 2024-11-10 +date: 2024-11-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 1447daf701420..2154e28257be1 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: 2024-11-10 +date: 2024-11-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 a4bb5abc40eba..0213b6758069d 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: 2024-11-10 +date: 2024-11-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_tabbed_modal.mdx b/api_docs/kbn_shared_ux_tabbed_modal.mdx index fba7362d90ec8..c62fa01ec55fb 100644 --- a/api_docs/kbn_shared_ux_tabbed_modal.mdx +++ b/api_docs/kbn_shared_ux_tabbed_modal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-tabbed-modal title: "@kbn/shared-ux-tabbed-modal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-tabbed-modal plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-tabbed-modal'] --- import kbnSharedUxTabbedModalObj from './kbn_shared_ux_tabbed_modal.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_table_persist.mdx b/api_docs/kbn_shared_ux_table_persist.mdx index ed3afe540319d..e7f71b4202e16 100644 --- a/api_docs/kbn_shared_ux_table_persist.mdx +++ b/api_docs/kbn_shared_ux_table_persist.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-table-persist title: "@kbn/shared-ux-table-persist" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-table-persist plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-table-persist'] --- import kbnSharedUxTablePersistObj from './kbn_shared_ux_table_persist.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index d1e21d7f7a4b2..a1dd4752be3c4 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: 2024-11-10 +date: 2024-11-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.mdx b/api_docs/kbn_slo_schema.mdx index 7f701dd4df27e..65288d331330a 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: 2024-11-10 +date: 2024-11-12 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 99a6d41a30c2f..4ce54ed82db65 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: 2024-11-10 +date: 2024-11-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_sort_predicates.mdx b/api_docs/kbn_sort_predicates.mdx index b3889f82599b2..bb4311fbbe760 100644 --- a/api_docs/kbn_sort_predicates.mdx +++ b/api_docs/kbn_sort_predicates.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-predicates title: "@kbn/sort-predicates" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-predicates plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-predicates'] --- import kbnSortPredicatesObj from './kbn_sort_predicates.devdocs.json'; diff --git a/api_docs/kbn_sse_utils.mdx b/api_docs/kbn_sse_utils.mdx index 205346bf5c085..5f1f5f18cde6c 100644 --- a/api_docs/kbn_sse_utils.mdx +++ b/api_docs/kbn_sse_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sse-utils title: "@kbn/sse-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sse-utils plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sse-utils'] --- import kbnSseUtilsObj from './kbn_sse_utils.devdocs.json'; diff --git a/api_docs/kbn_sse_utils_client.mdx b/api_docs/kbn_sse_utils_client.mdx index 39bb1195eb7d9..3d544b8d6aec1 100644 --- a/api_docs/kbn_sse_utils_client.mdx +++ b/api_docs/kbn_sse_utils_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sse-utils-client title: "@kbn/sse-utils-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sse-utils-client plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sse-utils-client'] --- import kbnSseUtilsClientObj from './kbn_sse_utils_client.devdocs.json'; diff --git a/api_docs/kbn_sse_utils_server.mdx b/api_docs/kbn_sse_utils_server.mdx index a952d8edf93a1..fba0e8dac86a5 100644 --- a/api_docs/kbn_sse_utils_server.mdx +++ b/api_docs/kbn_sse_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sse-utils-server title: "@kbn/sse-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sse-utils-server plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sse-utils-server'] --- import kbnSseUtilsServerObj from './kbn_sse_utils_server.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 15dd7e55782b2..91f1966b71162 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: 2024-11-10 +date: 2024-11-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 8e4d119dcefe8..2acd7cb283d4b 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: 2024-11-10 +date: 2024-11-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 4af5ab6dee0ba..1ccfe00076c40 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_synthetics_e2e.mdx b/api_docs/kbn_synthetics_e2e.mdx index 8c8b776b9b45f..bbe9eaf09a287 100644 --- a/api_docs/kbn_synthetics_e2e.mdx +++ b/api_docs/kbn_synthetics_e2e.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-synthetics-e2e title: "@kbn/synthetics-e2e" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/synthetics-e2e plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/synthetics-e2e'] --- import kbnSyntheticsE2eObj from './kbn_synthetics_e2e.devdocs.json'; diff --git a/api_docs/kbn_synthetics_private_location.mdx b/api_docs/kbn_synthetics_private_location.mdx index 18fea93d54253..bdfd0bec4dcc5 100644 --- a/api_docs/kbn_synthetics_private_location.mdx +++ b/api_docs/kbn_synthetics_private_location.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-synthetics-private-location title: "@kbn/synthetics-private-location" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/synthetics-private-location plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/synthetics-private-location'] --- import kbnSyntheticsPrivateLocationObj from './kbn_synthetics_private_location.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 7a6b63ecd4124..55dce0b7c0d93 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: 2024-11-10 +date: 2024-11-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 a15de1f6a5561..832fc1690f204 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_eui_helpers.mdx b/api_docs/kbn_test_eui_helpers.mdx index 3d9768a9ee345..7fafe9cc32bc6 100644 --- a/api_docs/kbn_test_eui_helpers.mdx +++ b/api_docs/kbn_test_eui_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-eui-helpers title: "@kbn/test-eui-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-eui-helpers plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-eui-helpers'] --- import kbnTestEuiHelpersObj from './kbn_test_eui_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.devdocs.json b/api_docs/kbn_test_jest_helpers.devdocs.json index a385640692703..805e169ca39b1 100644 --- a/api_docs/kbn_test_jest_helpers.devdocs.json +++ b/api_docs/kbn_test_jest_helpers.devdocs.json @@ -1006,7 +1006,7 @@ "label": "renderReactTestingLibraryWithI18n", "description": [], "signature": [ - "(ui: React.ReactElement>, options?: Omit<", + "(ui: React.ReactNode, options?: Omit<", "RenderOptions", ">, options?: Omit<", + "[ui: React.ReactNode, options?: Omit<", "RenderOptions", " | undefined; highlight?: Record | undefined; inner_hits?: Record | undefined; matched_queries?: string[] | undefined; _nested?: ", + "> | undefined; matched_queries?: string[] | Record | undefined; _nested?: ", "SearchNestedIdentity", - " | undefined; _ignored?: string[] | undefined; ignored_field_values?: Record | undefined; _shard?: string | undefined; _node?: string | undefined; _routing?: string | undefined; _rank?: number | undefined; _seq_no?: number | undefined; _primary_term?: number | undefined; _version?: number | undefined; sort?: ", + " | undefined; _ignored?: string[] | undefined; ignored_field_values?: Record | undefined; _shard?: string | undefined; _node?: string | undefined; _routing?: string | undefined; _rank?: number | undefined; _seq_no?: number | undefined; _primary_term?: number | undefined; _version?: number | undefined; sort?: ", "SortResults", " | undefined; }>; find: (findParams: { query?: string | undefined; start?: string | undefined; end?: string | undefined; sloId?: string | undefined; sloInstanceId?: string | undefined; serviceName?: string | undefined; filter?: string | undefined; size?: number | undefined; }) => Promise<{ items: { id: string | undefined; annotation: { title: string; type?: string | undefined; style?: { icon?: string | undefined; color?: string | undefined; line?: { width?: number | undefined; style?: \"dashed\" | \"solid\" | \"dotted\" | undefined; iconPosition?: \"top\" | \"bottom\" | undefined; textDecoration?: \"none\" | \"name\" | undefined; } | undefined; rect?: { fill?: \"inside\" | \"outside\" | undefined; } | undefined; } | undefined; }; '@timestamp': string; message: string; event?: ({ start: string; } & { end?: string | undefined; }) | undefined; tags?: string[] | undefined; service?: { name?: string | undefined; environment?: string | undefined; version?: string | undefined; } | undefined; monitor?: { id?: string | undefined; } | undefined; slo?: ({ id: string; } & { instanceId?: string | undefined; }) | undefined; host?: { name?: string | undefined; } | undefined; }[]; total: number; }>; delete: (deleteParams: { id: string; }) => Promise<", "DeleteByQueryResponse", @@ -12817,9 +12817,9 @@ "ExplainExplanation", " | undefined; fields?: Record | undefined; highlight?: Record | undefined; inner_hits?: Record | undefined; matched_queries?: string[] | undefined; _nested?: ", + "> | undefined; matched_queries?: string[] | Record | undefined; _nested?: ", "SearchNestedIdentity", - " | undefined; _ignored?: string[] | undefined; ignored_field_values?: Record | undefined; _shard?: string | undefined; _node?: string | undefined; _routing?: string | undefined; _rank?: number | undefined; _seq_no?: number | undefined; _primary_term?: number | undefined; _version?: number | undefined; sort?: ", + " | undefined; _ignored?: string[] | undefined; ignored_field_values?: Record | undefined; _shard?: string | undefined; _node?: string | undefined; _routing?: string | undefined; _rank?: number | undefined; _seq_no?: number | undefined; _primary_term?: number | undefined; _version?: number | undefined; sort?: ", "SortResults", " | undefined; }>; find: (findParams: { query?: string | undefined; start?: string | undefined; end?: string | undefined; sloId?: string | undefined; sloInstanceId?: string | undefined; serviceName?: string | undefined; filter?: string | undefined; size?: number | undefined; }) => Promise<{ items: { id: string | undefined; annotation: { title: string; type?: string | undefined; style?: { icon?: string | undefined; color?: string | undefined; line?: { width?: number | undefined; style?: \"dashed\" | \"solid\" | \"dotted\" | undefined; iconPosition?: \"top\" | \"bottom\" | undefined; textDecoration?: \"none\" | \"name\" | undefined; } | undefined; rect?: { fill?: \"inside\" | \"outside\" | undefined; } | undefined; } | undefined; }; '@timestamp': string; message: string; event?: ({ start: string; } & { end?: string | undefined; }) | undefined; tags?: string[] | undefined; service?: { name?: string | undefined; environment?: string | undefined; version?: string | undefined; } | undefined; monitor?: { id?: string | undefined; } | undefined; slo?: ({ id: string; } & { instanceId?: string | undefined; }) | undefined; host?: { name?: string | undefined; } | undefined; }[]; total: number; }>; delete: (deleteParams: { id: string; }) => Promise<", "DeleteByQueryResponse", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index d80f739ea4eca..9f014ee4f504b 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index 3f5579c41a4de..a5697831bc673 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant_app.mdx b/api_docs/observability_a_i_assistant_app.mdx index 9a6b43e0a175c..074b939139663 100644 --- a/api_docs/observability_a_i_assistant_app.mdx +++ b/api_docs/observability_a_i_assistant_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistantApp title: "observabilityAIAssistantApp" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistantApp plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistantApp'] --- import observabilityAIAssistantAppObj from './observability_a_i_assistant_app.devdocs.json'; diff --git a/api_docs/observability_ai_assistant_management.mdx b/api_docs/observability_ai_assistant_management.mdx index 24751d9e89f5a..7db6d8acbec8b 100644 --- a/api_docs/observability_ai_assistant_management.mdx +++ b/api_docs/observability_ai_assistant_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAiAssistantManagement title: "observabilityAiAssistantManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAiAssistantManagement plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAiAssistantManagement'] --- import observabilityAiAssistantManagementObj from './observability_ai_assistant_management.devdocs.json'; diff --git a/api_docs/observability_logs_explorer.mdx b/api_docs/observability_logs_explorer.mdx index 2fa25d54b86ed..096d438580b03 100644 --- a/api_docs/observability_logs_explorer.mdx +++ b/api_docs/observability_logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityLogsExplorer title: "observabilityLogsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityLogsExplorer plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityLogsExplorer'] --- import observabilityLogsExplorerObj from './observability_logs_explorer.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index 2386b5450ba81..49e61b7484f5d 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: 2024-11-10 +date: 2024-11-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 64a73a489b4ef..9c817ee1958b4 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: 2024-11-10 +date: 2024-11-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 c5287111fa891..d8542324ad381 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/painless_lab.mdx b/api_docs/painless_lab.mdx index 97772c39311ee..5e4cdb40148c5 100644 --- a/api_docs/painless_lab.mdx +++ b/api_docs/painless_lab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/painlessLab title: "painlessLab" image: https://source.unsplash.com/400x175/?github description: API docs for the painlessLab plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'painlessLab'] --- import painlessLabObj from './painless_lab.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index daa9a785426a9..450e68bfc2f45 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,13 +15,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 878 | 750 | 45 | +| 879 | 751 | 45 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 54142 | 240 | 40627 | 2000 | +| 54217 | 240 | 40700 | 2000 | ## Plugin Directory @@ -69,7 +69,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 35 | 0 | 33 | 2 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | A stateful layer to register shared features and provide an access point to discover without a direct dependency | 16 | 0 | 15 | 2 | | | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | APIs used to assess the quality of data in Elasticsearch indexes | 2 | 0 | 0 | 0 | -| | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | Server APIs for the Elastic AI Assistant | 52 | 0 | 37 | 2 | +| | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | Server APIs for the Elastic AI Assistant | 53 | 0 | 38 | 2 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 578 | 1 | 468 | 9 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Extends embeddable plugin with more functionality | 19 | 0 | 19 | 2 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 54 | 0 | 47 | 1 | @@ -184,7 +184,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 18 | 0 | 18 | 0 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 11 | 0 | 7 | 1 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | Plugin to provide access to and rendering of python notebooks for use in the persistent developer console. | 10 | 0 | 10 | 1 | -| | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 21 | 0 | 15 | 1 | +| | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 22 | 0 | 16 | 1 | | searchprofiler | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-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. | 455 | 0 | 238 | 0 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 188 | 0 | 120 | 33 | @@ -235,7 +235,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Registers the vega visualization. Is the elastic version of vega and vega-lite libraries. | 2 | 0 | 2 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains the vislib visualizations. These are the classical area/line/bar, gauge/goal and heatmap charts. We want to replace them with elastic-charts. | 1 | 0 | 1 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 52 | 0 | 50 | 5 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 872 | 12 | 841 | 20 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 871 | 12 | 840 | 20 | | watcher | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 0 | 0 | 0 | 0 | ## Package Directory @@ -547,6 +547,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 37 | 0 | 27 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 36 | 0 | 7 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 47 | 0 | 40 | 0 | +| | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 75 | 0 | 73 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 124 | 3 | 124 | 0 | | | [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai-infra) | - | 121 | 0 | 38 | 1 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 7 | 1 | 7 | 1 | @@ -575,7 +576,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 23 | 0 | 7 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 8 | 0 | 2 | 3 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 45 | 0 | 0 | 0 | -| | [@elastic/appex-sharedux @elastic/kibana-management](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 140 | 0 | 139 | 0 | +| | [@elastic/appex-sharedux @elastic/kibana-management](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 139 | 0 | 138 | 0 | | | [@elastic/appex-sharedux @elastic/kibana-management](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 20 | 0 | 11 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 88 | 0 | 10 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 56 | 0 | 6 | 0 | diff --git a/api_docs/presentation_panel.mdx b/api_docs/presentation_panel.mdx index f9ecadc3d4d07..0b7f9c31a9eab 100644 --- a/api_docs/presentation_panel.mdx +++ b/api_docs/presentation_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationPanel title: "presentationPanel" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationPanel plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationPanel'] --- import presentationPanelObj from './presentation_panel.devdocs.json'; diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index ab330280b81fa..206ed505ff730 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: 2024-11-10 +date: 2024-11-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 07d33ef2fa528..bf012bba8d611 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/profiling_data_access.mdx b/api_docs/profiling_data_access.mdx index 1f2f98966446c..d369f956a35ec 100644 --- a/api_docs/profiling_data_access.mdx +++ b/api_docs/profiling_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profilingDataAccess title: "profilingDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the profilingDataAccess plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profilingDataAccess'] --- import profilingDataAccessObj from './profiling_data_access.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 07cd882b80112..90127ece37af0 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: 2024-11-10 +date: 2024-11-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 c1f9d099d5286..fe3bdc4f656c6 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index fadca7cb9bdc1..2f5444d4041c0 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: 2024-11-10 +date: 2024-11-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 9921188605b31..33ff7e05af807 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: 2024-11-10 +date: 2024-11-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 7566e69c16f2a..12e54ddd24952 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: 2024-11-10 +date: 2024-11-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 491b871300911..3e3a002659d57 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: 2024-11-10 +date: 2024-11-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 5d94314705e01..5d82125c05cc0 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: 2024-11-10 +date: 2024-11-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 118c24136f5ef..393bb25c35ec8 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: 2024-11-10 +date: 2024-11-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 75a6b4174e58a..fb96c0c1637c8 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: 2024-11-10 +date: 2024-11-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 ead5baa3d5ac6..9a86f855006d1 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: 2024-11-10 +date: 2024-11-12 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 738c02dad4966..7aa957856f6f9 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: 2024-11-10 +date: 2024-11-12 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 71f5ab5571587..ecc45f81df2a7 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: 2024-11-10 +date: 2024-11-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 24fa328a75566..658acfa48d511 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/search_assistant.mdx b/api_docs/search_assistant.mdx index 7c1f19f27d53b..ad278f7e27145 100644 --- a/api_docs/search_assistant.mdx +++ b/api_docs/search_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchAssistant title: "searchAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the searchAssistant plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchAssistant'] --- import searchAssistantObj from './search_assistant.devdocs.json'; diff --git a/api_docs/search_connectors.mdx b/api_docs/search_connectors.mdx index dfe86ece22bfc..5c9b12c2ad9ca 100644 --- a/api_docs/search_connectors.mdx +++ b/api_docs/search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchConnectors title: "searchConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the searchConnectors plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchConnectors'] --- import searchConnectorsObj from './search_connectors.devdocs.json'; diff --git a/api_docs/search_homepage.mdx b/api_docs/search_homepage.mdx index 6e389b22c5927..b19d497edcd82 100644 --- a/api_docs/search_homepage.mdx +++ b/api_docs/search_homepage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchHomepage title: "searchHomepage" image: https://source.unsplash.com/400x175/?github description: API docs for the searchHomepage plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchHomepage'] --- import searchHomepageObj from './search_homepage.devdocs.json'; diff --git a/api_docs/search_indices.devdocs.json b/api_docs/search_indices.devdocs.json index 2a5d681533d15..11be05829ab55 100644 --- a/api_docs/search_indices.devdocs.json +++ b/api_docs/search_indices.devdocs.json @@ -85,7 +85,7 @@ "label": "startAppId", "description": [], "signature": [ - "\"fleet\" | \"graph\" | \"ml\" | \"monitoring\" | \"profiling\" | \"metrics\" | \"management\" | \"apm\" | \"synthetics\" | \"ux\" | \"canvas\" | \"logs\" | \"dashboards\" | \"slo\" | \"observabilityAIAssistant\" | \"home\" | \"integrations\" | \"discover\" | \"observability-overview\" | \"appSearch\" | \"dev_tools\" | \"maps\" | \"visualize\" | \"dev_tools:console\" | \"dev_tools:searchprofiler\" | \"dev_tools:painless_lab\" | \"dev_tools:grokdebugger\" | \"ml:notifications\" | \"ml:nodes\" | \"ml:overview\" | \"ml:memoryUsage\" | \"ml:settings\" | \"ml:dataVisualizer\" | \"ml:logPatternAnalysis\" | \"ml:logRateAnalysis\" | \"ml:singleMetricViewer\" | \"ml:anomalyDetection\" | \"ml:anomalyExplorer\" | \"ml:dataDrift\" | \"ml:dataFrameAnalytics\" | \"ml:resultExplorer\" | \"ml:analyticsMap\" | \"ml:aiOps\" | \"ml:changePointDetections\" | \"ml:modelManagement\" | \"ml:nodesOverview\" | \"ml:esqlDataVisualizer\" | \"ml:fileUpload\" | \"ml:indexDataVisualizer\" | \"ml:calendarSettings\" | \"ml:filterListsSettings\" | \"ml:suppliedConfigurations\" | \"osquery\" | \"management:transform\" | \"management:watcher\" | \"management:cases\" | \"management:tags\" | \"management:maintenanceWindows\" | \"management:cross_cluster_replication\" | \"management:dataViews\" | \"management:spaces\" | \"management:settings\" | \"management:users\" | \"management:migrate_data\" | \"management:search_sessions\" | \"management:data_quality\" | \"management:filesManagement\" | \"management:roles\" | \"management:reporting\" | \"management:aiAssistantManagementSelection\" | \"management:securityAiAssistantManagement\" | \"management:observabilityAiAssistantManagement\" | \"management:api_keys\" | \"management:license_management\" | \"management:index_lifecycle_management\" | \"management:index_management\" | \"management:ingest_pipelines\" | \"management:jobsListLink\" | \"management:objects\" | \"management:pipelines\" | \"management:remote_clusters\" | \"management:role_mappings\" | \"management:rollup_jobs\" | \"management:snapshot_restore\" | \"management:triggersActions\" | \"management:triggersActionsConnectors\" | \"management:upgrade_assistant\" | \"enterpriseSearch\" | \"enterpriseSearchContent\" | \"enterpriseSearchApplications\" | \"searchInferenceEndpoints\" | \"enterpriseSearchAnalytics\" | \"workplaceSearch\" | \"serverlessElasticsearch\" | \"serverlessConnectors\" | \"searchPlayground\" | \"searchHomepage\" | \"enterpriseSearchContent:connectors\" | \"enterpriseSearchContent:searchIndices\" | \"enterpriseSearchContent:webCrawlers\" | \"enterpriseSearchApplications:searchApplications\" | \"enterpriseSearchApplications:playground\" | \"appSearch:engines\" | \"searchInferenceEndpoints:inferenceEndpoints\" | \"elasticsearchStart\" | \"elasticsearchIndices\" | \"enterpriseSearchElasticsearch\" | \"enterpriseSearchVectorSearch\" | \"enterpriseSearchSemanticSearch\" | \"enterpriseSearchAISearch\" | \"observability-logs-explorer\" | \"last-used-logs-viewer\" | \"observabilityOnboarding\" | \"inventory\" | \"logs:settings\" | \"logs:stream\" | \"logs:log-categories\" | \"logs:anomalies\" | \"observability-overview:cases\" | \"observability-overview:alerts\" | \"observability-overview:rules\" | \"observability-overview:cases_create\" | \"observability-overview:cases_configure\" | \"metrics:settings\" | \"metrics:hosts\" | \"metrics:inventory\" | \"metrics:metrics-explorer\" | \"metrics:assetDetails\" | \"apm:services\" | \"apm:traces\" | \"apm:dependencies\" | \"apm:service-map\" | \"apm:settings\" | \"apm:service-groups-list\" | \"apm:storage-explorer\" | \"synthetics:overview\" | \"synthetics:certificates\" | \"profiling:functions\" | \"profiling:stacktraces\" | \"profiling:flamegraphs\" | \"inventory:datastreams\" | \"securitySolutionUI\" | \"securitySolutionUI:\" | \"securitySolutionUI:cases\" | \"securitySolutionUI:alerts\" | \"securitySolutionUI:rules\" | \"securitySolutionUI:policy\" | \"securitySolutionUI:overview\" | \"securitySolutionUI:dashboards\" | \"securitySolutionUI:kubernetes\" | \"securitySolutionUI:cases_create\" | \"securitySolutionUI:cases_configure\" | \"securitySolutionUI:hosts\" | \"securitySolutionUI:users\" | \"securitySolutionUI:cloud_defend-policies\" | \"securitySolutionUI:cloud_security_posture-dashboard\" | \"securitySolutionUI:cloud_security_posture-findings\" | \"securitySolutionUI:cloud_security_posture-benchmarks\" | \"securitySolutionUI:network\" | \"securitySolutionUI:data_quality\" | \"securitySolutionUI:explore\" | \"securitySolutionUI:assets\" | \"securitySolutionUI:cloud_defend\" | \"securitySolutionUI:notes\" | \"securitySolutionUI:administration\" | \"securitySolutionUI:attack_discovery\" | \"securitySolutionUI:blocklist\" | \"securitySolutionUI:cloud_security_posture-rules\" | \"securitySolutionUI:detections\" | \"securitySolutionUI:detection_response\" | \"securitySolutionUI:endpoints\" | \"securitySolutionUI:event_filters\" | \"securitySolutionUI:exceptions\" | \"securitySolutionUI:host_isolation_exceptions\" | \"securitySolutionUI:hosts-all\" | \"securitySolutionUI:hosts-anomalies\" | \"securitySolutionUI:hosts-risk\" | \"securitySolutionUI:hosts-events\" | \"securitySolutionUI:hosts-sessions\" | \"securitySolutionUI:hosts-uncommon_processes\" | \"securitySolutionUI:investigations\" | \"securitySolutionUI:get_started\" | \"securitySolutionUI:machine_learning-landing\" | \"securitySolutionUI:network-anomalies\" | \"securitySolutionUI:network-dns\" | \"securitySolutionUI:network-events\" | \"securitySolutionUI:network-flows\" | \"securitySolutionUI:network-http\" | \"securitySolutionUI:network-tls\" | \"securitySolutionUI:response_actions_history\" | \"securitySolutionUI:rules-add\" | \"securitySolutionUI:rules-create\" | \"securitySolutionUI:rules-landing\" | \"securitySolutionUI:threat_intelligence\" | \"securitySolutionUI:timelines\" | \"securitySolutionUI:timelines-templates\" | \"securitySolutionUI:trusted_apps\" | \"securitySolutionUI:users-all\" | \"securitySolutionUI:users-anomalies\" | \"securitySolutionUI:users-authentications\" | \"securitySolutionUI:users-events\" | \"securitySolutionUI:users-risk\" | \"securitySolutionUI:entity_analytics\" | \"securitySolutionUI:entity_analytics-management\" | \"securitySolutionUI:entity_analytics-asset-classification\" | \"securitySolutionUI:entity_analytics-entity_store_management\" | \"securitySolutionUI:coverage-overview\" | \"fleet:settings\" | \"fleet:agents\" | \"fleet:policies\" | \"fleet:data_streams\" | \"fleet:enrollment_tokens\" | \"fleet:uninstall_tokens\"" + "\"fleet\" | \"graph\" | \"ml\" | \"monitoring\" | \"profiling\" | \"metrics\" | \"management\" | \"apm\" | \"synthetics\" | \"ux\" | \"canvas\" | \"logs\" | \"dashboards\" | \"slo\" | \"observabilityAIAssistant\" | \"home\" | \"integrations\" | \"discover\" | \"observability-overview\" | \"appSearch\" | \"dev_tools\" | \"maps\" | \"visualize\" | \"dev_tools:console\" | \"dev_tools:searchprofiler\" | \"dev_tools:painless_lab\" | \"dev_tools:grokdebugger\" | \"ml:notifications\" | \"ml:nodes\" | \"ml:overview\" | \"ml:memoryUsage\" | \"ml:settings\" | \"ml:dataVisualizer\" | \"ml:logPatternAnalysis\" | \"ml:logRateAnalysis\" | \"ml:singleMetricViewer\" | \"ml:anomalyDetection\" | \"ml:anomalyExplorer\" | \"ml:dataDrift\" | \"ml:dataFrameAnalytics\" | \"ml:resultExplorer\" | \"ml:analyticsMap\" | \"ml:aiOps\" | \"ml:changePointDetections\" | \"ml:modelManagement\" | \"ml:nodesOverview\" | \"ml:esqlDataVisualizer\" | \"ml:fileUpload\" | \"ml:indexDataVisualizer\" | \"ml:calendarSettings\" | \"ml:filterListsSettings\" | \"ml:suppliedConfigurations\" | \"osquery\" | \"management:transform\" | \"management:watcher\" | \"management:cases\" | \"management:tags\" | \"management:maintenanceWindows\" | \"management:cross_cluster_replication\" | \"management:dataViews\" | \"management:spaces\" | \"management:settings\" | \"management:users\" | \"management:migrate_data\" | \"management:search_sessions\" | \"management:data_quality\" | \"management:filesManagement\" | \"management:roles\" | \"management:reporting\" | \"management:aiAssistantManagementSelection\" | \"management:securityAiAssistantManagement\" | \"management:observabilityAiAssistantManagement\" | \"management:api_keys\" | \"management:license_management\" | \"management:index_lifecycle_management\" | \"management:index_management\" | \"management:ingest_pipelines\" | \"management:jobsListLink\" | \"management:objects\" | \"management:pipelines\" | \"management:remote_clusters\" | \"management:role_mappings\" | \"management:rollup_jobs\" | \"management:snapshot_restore\" | \"management:triggersActions\" | \"management:triggersActionsConnectors\" | \"management:upgrade_assistant\" | \"enterpriseSearch\" | \"enterpriseSearchContent\" | \"enterpriseSearchApplications\" | \"searchInferenceEndpoints\" | \"enterpriseSearchAnalytics\" | \"workplaceSearch\" | \"serverlessElasticsearch\" | \"serverlessConnectors\" | \"searchPlayground\" | \"searchHomepage\" | \"enterpriseSearchContent:connectors\" | \"enterpriseSearchContent:searchIndices\" | \"enterpriseSearchContent:webCrawlers\" | \"enterpriseSearchApplications:searchApplications\" | \"enterpriseSearchApplications:playground\" | \"appSearch:engines\" | \"searchInferenceEndpoints:inferenceEndpoints\" | \"elasticsearchStart\" | \"elasticsearchIndices\" | \"enterpriseSearchElasticsearch\" | \"enterpriseSearchVectorSearch\" | \"enterpriseSearchSemanticSearch\" | \"enterpriseSearchAISearch\" | \"elasticsearchIndices:createIndex\" | \"observability-logs-explorer\" | \"last-used-logs-viewer\" | \"observabilityOnboarding\" | \"inventory\" | \"logs:settings\" | \"logs:stream\" | \"logs:log-categories\" | \"logs:anomalies\" | \"observability-overview:cases\" | \"observability-overview:alerts\" | \"observability-overview:rules\" | \"observability-overview:cases_create\" | \"observability-overview:cases_configure\" | \"metrics:settings\" | \"metrics:hosts\" | \"metrics:inventory\" | \"metrics:metrics-explorer\" | \"metrics:assetDetails\" | \"apm:services\" | \"apm:traces\" | \"apm:dependencies\" | \"apm:service-map\" | \"apm:settings\" | \"apm:service-groups-list\" | \"apm:storage-explorer\" | \"synthetics:overview\" | \"synthetics:certificates\" | \"profiling:functions\" | \"profiling:stacktraces\" | \"profiling:flamegraphs\" | \"inventory:datastreams\" | \"securitySolutionUI\" | \"securitySolutionUI:\" | \"securitySolutionUI:cases\" | \"securitySolutionUI:alerts\" | \"securitySolutionUI:rules\" | \"securitySolutionUI:policy\" | \"securitySolutionUI:overview\" | \"securitySolutionUI:dashboards\" | \"securitySolutionUI:kubernetes\" | \"securitySolutionUI:cases_create\" | \"securitySolutionUI:cases_configure\" | \"securitySolutionUI:hosts\" | \"securitySolutionUI:users\" | \"securitySolutionUI:cloud_defend-policies\" | \"securitySolutionUI:cloud_security_posture-dashboard\" | \"securitySolutionUI:cloud_security_posture-findings\" | \"securitySolutionUI:cloud_security_posture-benchmarks\" | \"securitySolutionUI:network\" | \"securitySolutionUI:data_quality\" | \"securitySolutionUI:explore\" | \"securitySolutionUI:assets\" | \"securitySolutionUI:cloud_defend\" | \"securitySolutionUI:notes\" | \"securitySolutionUI:administration\" | \"securitySolutionUI:attack_discovery\" | \"securitySolutionUI:blocklist\" | \"securitySolutionUI:cloud_security_posture-rules\" | \"securitySolutionUI:detections\" | \"securitySolutionUI:detection_response\" | \"securitySolutionUI:endpoints\" | \"securitySolutionUI:event_filters\" | \"securitySolutionUI:exceptions\" | \"securitySolutionUI:host_isolation_exceptions\" | \"securitySolutionUI:hosts-all\" | \"securitySolutionUI:hosts-anomalies\" | \"securitySolutionUI:hosts-risk\" | \"securitySolutionUI:hosts-events\" | \"securitySolutionUI:hosts-sessions\" | \"securitySolutionUI:hosts-uncommon_processes\" | \"securitySolutionUI:investigations\" | \"securitySolutionUI:get_started\" | \"securitySolutionUI:machine_learning-landing\" | \"securitySolutionUI:network-anomalies\" | \"securitySolutionUI:network-dns\" | \"securitySolutionUI:network-events\" | \"securitySolutionUI:network-flows\" | \"securitySolutionUI:network-http\" | \"securitySolutionUI:network-tls\" | \"securitySolutionUI:response_actions_history\" | \"securitySolutionUI:rules-add\" | \"securitySolutionUI:rules-create\" | \"securitySolutionUI:rules-landing\" | \"securitySolutionUI:threat_intelligence\" | \"securitySolutionUI:timelines\" | \"securitySolutionUI:timelines-templates\" | \"securitySolutionUI:trusted_apps\" | \"securitySolutionUI:users-all\" | \"securitySolutionUI:users-anomalies\" | \"securitySolutionUI:users-authentications\" | \"securitySolutionUI:users-events\" | \"securitySolutionUI:users-risk\" | \"securitySolutionUI:entity_analytics\" | \"securitySolutionUI:entity_analytics-management\" | \"securitySolutionUI:entity_analytics-asset-classification\" | \"securitySolutionUI:entity_analytics-entity_store_management\" | \"securitySolutionUI:coverage-overview\" | \"fleet:settings\" | \"fleet:agents\" | \"fleet:policies\" | \"fleet:data_streams\" | \"fleet:enrollment_tokens\" | \"fleet:uninstall_tokens\"" ], "path": "x-pack/plugins/search_indices/public/types.ts", "deprecated": false, diff --git a/api_docs/search_indices.mdx b/api_docs/search_indices.mdx index b2100c97e4e85..9f24d98efc5ee 100644 --- a/api_docs/search_indices.mdx +++ b/api_docs/search_indices.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchIndices title: "searchIndices" image: https://source.unsplash.com/400x175/?github description: API docs for the searchIndices plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchIndices'] --- import searchIndicesObj from './search_indices.devdocs.json'; diff --git a/api_docs/search_inference_endpoints.mdx b/api_docs/search_inference_endpoints.mdx index 994ccfc5b4b11..2f982d4bd9f2f 100644 --- a/api_docs/search_inference_endpoints.mdx +++ b/api_docs/search_inference_endpoints.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchInferenceEndpoints title: "searchInferenceEndpoints" image: https://source.unsplash.com/400x175/?github description: API docs for the searchInferenceEndpoints plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchInferenceEndpoints'] --- import searchInferenceEndpointsObj from './search_inference_endpoints.devdocs.json'; diff --git a/api_docs/search_notebooks.mdx b/api_docs/search_notebooks.mdx index d648b1a534cd0..9c6cc120f9d5c 100644 --- a/api_docs/search_notebooks.mdx +++ b/api_docs/search_notebooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchNotebooks title: "searchNotebooks" image: https://source.unsplash.com/400x175/?github description: API docs for the searchNotebooks plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchNotebooks'] --- import searchNotebooksObj from './search_notebooks.devdocs.json'; diff --git a/api_docs/search_playground.devdocs.json b/api_docs/search_playground.devdocs.json index 17d790c21d72f..c097d00d40a15 100644 --- a/api_docs/search_playground.devdocs.json +++ b/api_docs/search_playground.devdocs.json @@ -4,7 +4,20 @@ "classes": [], "functions": [], "interfaces": [], - "enums": [], + "enums": [ + { + "parentPluginId": "searchPlayground", + "id": "def-public.PlaygroundPageMode", + "type": "Enum", + "tags": [], + "label": "PlaygroundPageMode", + "description": [], + "path": "x-pack/plugins/search_playground/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], "misc": [], "objects": [], "setup": { diff --git a/api_docs/search_playground.mdx b/api_docs/search_playground.mdx index 403fc7d682cda..e4f76b15cc210 100644 --- a/api_docs/search_playground.mdx +++ b/api_docs/search_playground.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchPlayground title: "searchPlayground" image: https://source.unsplash.com/400x175/?github description: API docs for the searchPlayground plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchPlayground'] --- import searchPlaygroundObj from './search_playground.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-ki | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 21 | 0 | 15 | 1 | +| 22 | 0 | 16 | 1 | ## Client @@ -31,6 +31,9 @@ Contact [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-ki ### Start +### Enums + + ## Server ### Setup diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 34f62d1079a7c..f2a9ff6f5a85a 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: 2024-11-10 +date: 2024-11-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 cf577629871c7..8c458c5dd5c90 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: 2024-11-10 +date: 2024-11-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 c4bea975988c2..09498b8b44411 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: 2024-11-10 +date: 2024-11-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 62018e2ccdd41..e85832e528bda 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: 2024-11-10 +date: 2024-11-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 3b1fc801bb820..834b2849bf4fc 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: 2024-11-10 +date: 2024-11-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 b9f62ae5a5cc4..ab9d0dafee7dc 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: 2024-11-10 +date: 2024-11-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 3eb9d112921d5..42e3a4a3621d1 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: 2024-11-10 +date: 2024-11-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 c8d9e01e24b9b..0fe1099b64752 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: 2024-11-10 +date: 2024-11-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 0edc2ef35af65..9a754c7f4216a 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/slo.mdx b/api_docs/slo.mdx index 76877cd128826..25f86f6999c9d 100644 --- a/api_docs/slo.mdx +++ b/api_docs/slo.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/slo title: "slo" image: https://source.unsplash.com/400x175/?github description: API docs for the slo plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'slo'] --- import sloObj from './slo.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index deee9fdb541a2..0db83bcf54f2f 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: 2024-11-10 +date: 2024-11-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 31865d22e5f25..b0cd89257784f 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: 2024-11-10 +date: 2024-11-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 4cfcbc6251dc3..ffe989d464af3 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: 2024-11-10 +date: 2024-11-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 103cb9696b4b7..5c1c4923420bc 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: 2024-11-10 +date: 2024-11-12 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 70bdd783a5209..3c670603eb893 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: 2024-11-10 +date: 2024-11-12 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 60dbb98e2ab1c..43819592c035e 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: 2024-11-10 +date: 2024-11-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 72c605c6c1dfa..eca4387248451 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 0dabf140492db..1c5b7f448713a 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 7ae72ce36d8f7..b2ad8e21aff35 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: 2024-11-10 +date: 2024-11-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 d40bd69ad446e..fbacc1e90a620 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: 2024-11-10 +date: 2024-11-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 ecedd96703059..291701282c819 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: 2024-11-10 +date: 2024-11-12 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 ba5312049eed5..fffd0501602d6 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: 2024-11-10 +date: 2024-11-12 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 6ab39442c68e4..92773d1487397 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: 2024-11-10 +date: 2024-11-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 80b5b40d74e20..1222419d87c9b 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_doc_viewer.mdx b/api_docs/unified_doc_viewer.mdx index 8fd6c87236457..6613e34f43657 100644 --- a/api_docs/unified_doc_viewer.mdx +++ b/api_docs/unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedDocViewer title: "unifiedDocViewer" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedDocViewer plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedDocViewer'] --- import unifiedDocViewerObj from './unified_doc_viewer.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 3b74c67464fd3..14165a4707ea3 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: 2024-11-10 +date: 2024-11-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 55716f98e2008..176451a11b83d 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: 2024-11-10 +date: 2024-11-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 eda199e57b834..7f85dc30a86de 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/uptime.mdx b/api_docs/uptime.mdx index 2b537d4507d08..868b1e28155df 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uptime'] --- import uptimeObj from './uptime.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 9ff8d507cecf6..45c1fcb5ea0b0 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: 2024-11-10 +date: 2024-11-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 8707950662e17..fbd8706e92a6a 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: 2024-11-10 +date: 2024-11-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 85d480beecafc..b623525fb2cf1 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: 2024-11-10 +date: 2024-11-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 2342e5aa55692..2860a5adf69ce 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: 2024-11-10 +date: 2024-11-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 ff5ef4fd5d2f9..717b780a8b2b2 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: 2024-11-10 +date: 2024-11-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 c4707e4e80795..e15ce6607d5e8 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: 2024-11-10 +date: 2024-11-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 7c5e17d7aa3c6..cdc9a04b9baa7 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: 2024-11-10 +date: 2024-11-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 6b3471e086144..dae1914194af1 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: 2024-11-10 +date: 2024-11-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 41f321cff8c43..cfa2d3463f782 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: 2024-11-10 +date: 2024-11-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 38d8f5afeca7a..4baff6787751d 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: 2024-11-10 +date: 2024-11-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 8726e55be8332..d21887d0ab6a8 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: 2024-11-10 +date: 2024-11-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 64dbbbbf238d0..11f32e53b40e4 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: 2024-11-10 +date: 2024-11-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 785f62076ab15..bb4c1e7c59b19 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.devdocs.json b/api_docs/visualizations.devdocs.json index bcaf2ac9154d3..d2d15673ef452 100644 --- a/api_docs/visualizations.devdocs.json +++ b/api_docs/visualizations.devdocs.json @@ -336,20 +336,6 @@ "deprecated": false, "trackAdoption": false }, - { - "parentPluginId": "visualizations", - "id": "def-public.BaseVisType.suppressWarnings", - "type": "Function", - "tags": [], - "label": "suppressWarnings", - "description": [], - "signature": [ - "(() => boolean) | undefined" - ], - "path": "src/plugins/visualizations/public/vis_types/base_vis_type.ts", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "visualizations", "id": "def-public.BaseVisType.hasPartialRows", diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index abda17709cebd..78840e906c6ac 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: 2024-11-10 +date: 2024-11-12 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.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 | |-------------------|-----------|------------------------|-----------------| -| 872 | 12 | 841 | 20 | +| 871 | 12 | 840 | 20 | ## Client From e87fbd8c241d9327df6dc4ad1942447fa99276fb Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 12 Nov 2024 09:03:50 +0100 Subject: [PATCH 003/105] [ES|QL] Group by histogram suggestion first in the list (#199611) ## Summary Ensures that group BY histogram suggestion is first on the list. It fixes a regression caused from the refactoring of autocomplete image ### 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 --- .../src/autocomplete/commands/stats/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/commands/stats/util.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/commands/stats/util.ts index c9abaa5c5408a..0730b004e28d2 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/commands/stats/util.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/commands/stats/util.ts @@ -99,6 +99,6 @@ export const getDateHistogramCompletionItem: ( defaultMessage: 'Add date histogram using bucket()', } ), - sortText: '1A', + sortText: '1', command: TRIGGER_SUGGESTION_COMMAND, }); From dbc9e31dbccd5a743c85b3a52692fd950c0aa292 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Tue, 12 Nov 2024 09:04:01 +0100 Subject: [PATCH 004/105] [ES|QL] Marks tech preview functions in the editor (#199631) ## Summary Closes https://github.com/elastic/kibana/issues/194062 Indicates tech preview functions in the editor. ![image (62)](https://github.com/user-attachments/assets/a6d2b1e8-f7c7-4bee-8a9f-3c9d5026c79e) --- .../scripts/generate_function_definitions.ts | 5 + .../src/autocomplete/factories.ts | 13 ++- .../generated/aggregation_functions.ts | 13 +++ .../definitions/generated/scalar_functions.ts | 104 +++++++++++++++++- .../src/definitions/types.ts | 1 + 5 files changed, 134 insertions(+), 2 deletions(-) diff --git a/packages/kbn-esql-validation-autocomplete/scripts/generate_function_definitions.ts b/packages/kbn-esql-validation-autocomplete/scripts/generate_function_definitions.ts index fe2a85456aa12..4f649b44e44b8 100644 --- a/packages/kbn-esql-validation-autocomplete/scripts/generate_function_definitions.ts +++ b/packages/kbn-esql-validation-autocomplete/scripts/generate_function_definitions.ts @@ -255,6 +255,7 @@ function getFunctionDefinition(ESFunctionDefinition: Record): Funct description: ESFunctionDefinition.description, alias: aliasTable[ESFunctionDefinition.name], ignoreAsSuggestion: ESFunctionDefinition.snapshot_only, + preview: ESFunctionDefinition.preview, signatures: _.uniqBy( ESFunctionDefinition.signatures.map((signature: any) => ({ ...signature, @@ -334,6 +335,7 @@ function printGeneratedFunctionsFile( description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.${name}', { defaultMessage: ${JSON.stringify( removeAsciiDocInternalCrossReferences(removeInlineAsciiDocLinks(description), functionNames) )} }),${functionDefinition.ignoreAsSuggestion ? 'ignoreAsSuggestion: true,\n' : ''} + preview: ${functionDefinition.preview || 'false'}, alias: ${alias ? `['${alias.join("', '")}']` : 'undefined'}, signatures: ${JSON.stringify(signatures, null, 2)}, supportedCommands: ${JSON.stringify(functionDefinition.supportedCommands)}, @@ -393,6 +395,9 @@ import { isLiteralItem } from '../../shared/helpers';` (async function main() { const pathToElasticsearch = process.argv[2]; + if (!pathToElasticsearch) { + throw new Error('Path to Elasticsearch is required'); + } const ESFunctionDefinitionsDirectory = join( pathToElasticsearch, diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts index 88560f6d2f4c5..d9813bb0e91a1 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts @@ -30,6 +30,13 @@ import { isNumericType } from '../shared/esql_types'; import { getTestFunctions } from '../shared/test_functions'; import { builtinFunctions } from '../definitions/builtin'; +const techPreviewLabel = i18n.translate( + 'kbn-esql-validation-autocomplete.esql.autocomplete.techPreviewLabel', + { + defaultMessage: `Technical Preview`, + } +); + const allFunctions = memoize( () => aggregationFunctionDefinitions @@ -60,13 +67,17 @@ function getSafeInsertSourceText(text: string) { } export function getFunctionSuggestion(fn: FunctionDefinition): SuggestionRawDefinition { + let detail = fn.description; + if (fn.preview) { + detail = `[${techPreviewLabel}] ${detail}`; + } const fullSignatures = getFunctionSignatures(fn, { capitalize: true, withTypes: true }); return { label: fn.name.toUpperCase(), text: `${fn.name.toUpperCase()}($0)`, asSnippet: true, kind: 'Function', - detail: fn.description, + detail, documentation: { value: buildFunctionDocumentation(fullSignatures, fn.examples), }, diff --git a/packages/kbn-esql-validation-autocomplete/src/definitions/generated/aggregation_functions.ts b/packages/kbn-esql-validation-autocomplete/src/definitions/generated/aggregation_functions.ts index f73521ddf3a87..6a429f2288f94 100644 --- a/packages/kbn-esql-validation-autocomplete/src/definitions/generated/aggregation_functions.ts +++ b/packages/kbn-esql-validation-autocomplete/src/definitions/generated/aggregation_functions.ts @@ -36,6 +36,7 @@ const avgDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.avg', { defaultMessage: 'The average of a numeric field.', }), + preview: false, alias: undefined, signatures: [ { @@ -85,6 +86,7 @@ const countDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.count', { defaultMessage: 'Returns the total number (count) of input values.', }), + preview: false, alias: undefined, signatures: [ { @@ -228,6 +230,7 @@ const countDistinctDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.count_distinct', { defaultMessage: 'Returns the approximate number of distinct values.', }), + preview: false, alias: undefined, signatures: [ { @@ -743,6 +746,7 @@ const maxDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.max', { defaultMessage: 'The maximum value of a field.', }), + preview: false, alias: undefined, signatures: [ { @@ -853,6 +857,7 @@ const medianDefinition: FunctionDefinition = { defaultMessage: 'The value that is greater than half of all values and less than half of all values, also known as the 50% `PERCENTILE`.', }), + preview: false, alias: undefined, signatures: [ { @@ -906,6 +911,7 @@ const medianAbsoluteDeviationDefinition: FunctionDefinition = { "Returns the median absolute deviation, a measure of variability. It is a robust statistic, meaning that it is useful for describing data that may have outliers, or may not be normally distributed. For such data it can be more descriptive than standard deviation.\n\nIt is calculated as the median of each data point's deviation from the median of the entire sample. That is, for a random variable `X`, the median absolute deviation is `median(|median(X) - X|)`.", } ), + preview: false, alias: undefined, signatures: [ { @@ -955,6 +961,7 @@ const minDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.min', { defaultMessage: 'The minimum value of a field.', }), + preview: false, alias: undefined, signatures: [ { @@ -1065,6 +1072,7 @@ const percentileDefinition: FunctionDefinition = { defaultMessage: 'Returns the value at which a certain percentage of observed values occur. For example, the 95th percentile is the value which is greater than 95% of the observed values and the 50th percentile is the `MEDIAN`.', }), + preview: false, alias: undefined, signatures: [ { @@ -1228,6 +1236,7 @@ const stCentroidAggDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.st_centroid_agg', { defaultMessage: 'Calculate the spatial centroid over a field with spatial point geometry type.', }), + preview: false, alias: undefined, signatures: [ { @@ -1264,6 +1273,7 @@ const sumDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.sum', { defaultMessage: 'The sum of a numeric expression.', }), + preview: false, alias: undefined, signatures: [ { @@ -1313,6 +1323,7 @@ const topDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.top', { defaultMessage: 'Collects the top values for a field. Includes repeated values.', }), + preview: false, alias: undefined, signatures: [ { @@ -1510,6 +1521,7 @@ const valuesDefinition: FunctionDefinition = { defaultMessage: "Returns all values in a group as a multivalued field. The order of the returned values isn't guaranteed. If you need the values returned in order use esql-mv_sort.", }), + preview: true, alias: undefined, signatures: [ { @@ -1618,6 +1630,7 @@ const weightedAvgDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.weighted_avg', { defaultMessage: 'The weighted average of a numeric expression.', }), + preview: false, alias: undefined, signatures: [ { diff --git a/packages/kbn-esql-validation-autocomplete/src/definitions/generated/scalar_functions.ts b/packages/kbn-esql-validation-autocomplete/src/definitions/generated/scalar_functions.ts index 739a12095ac23..7e9019aeb905a 100644 --- a/packages/kbn-esql-validation-autocomplete/src/definitions/generated/scalar_functions.ts +++ b/packages/kbn-esql-validation-autocomplete/src/definitions/generated/scalar_functions.ts @@ -38,6 +38,7 @@ const absDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.abs', { defaultMessage: 'Returns the absolute value.', }), + preview: false, alias: undefined, signatures: [ { @@ -97,6 +98,7 @@ const acosDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.acos', { defaultMessage: 'Returns the arccosine of `n` as an angle, expressed in radians.', }), + preview: false, alias: undefined, signatures: [ { @@ -154,6 +156,7 @@ const asinDefinition: FunctionDefinition = { defaultMessage: 'Returns the arcsine of the input\nnumeric expression as an angle, expressed in radians.', }), + preview: false, alias: undefined, signatures: [ { @@ -211,6 +214,7 @@ const atanDefinition: FunctionDefinition = { defaultMessage: 'Returns the arctangent of the input\nnumeric expression as an angle, expressed in radians.', }), + preview: false, alias: undefined, signatures: [ { @@ -268,6 +272,7 @@ const atan2Definition: FunctionDefinition = { defaultMessage: 'The angle between the positive x-axis and the ray from the\norigin to the point (x , y) in the Cartesian plane, expressed in radians.', }), + preview: false, alias: undefined, signatures: [ { @@ -526,6 +531,7 @@ const categorizeDefinition: FunctionDefinition = { }), ignoreAsSuggestion: true, + preview: false, alias: undefined, signatures: [ { @@ -563,6 +569,7 @@ const cbrtDefinition: FunctionDefinition = { defaultMessage: 'Returns the cube root of a number. The input can be any numeric value, the return value is always a double.\nCube roots of infinities are null.', }), + preview: false, alias: undefined, signatures: [ { @@ -619,6 +626,7 @@ const ceilDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.ceil', { defaultMessage: 'Round a number up to the nearest integer.', }), + preview: false, alias: undefined, signatures: [ { @@ -676,6 +684,7 @@ const cidrMatchDefinition: FunctionDefinition = { defaultMessage: 'Returns true if the provided IP is contained in one of the provided CIDR blocks.', }), + preview: false, alias: undefined, signatures: [ { @@ -727,6 +736,7 @@ const coalesceDefinition: FunctionDefinition = { defaultMessage: 'Returns the first of its arguments that is not null. If all arguments are null, it returns `null`.', }), + preview: false, alias: undefined, signatures: [ { @@ -990,6 +1000,7 @@ const concatDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.concat', { defaultMessage: 'Concatenates two or more strings.', }), + preview: false, alias: undefined, signatures: [ { @@ -1072,6 +1083,7 @@ const cosDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.cos', { defaultMessage: 'Returns the cosine of an angle.', }), + preview: false, alias: undefined, signatures: [ { @@ -1128,6 +1140,7 @@ const coshDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.cosh', { defaultMessage: 'Returns the hyperbolic cosine of a number.', }), + preview: false, alias: undefined, signatures: [ { @@ -1185,6 +1198,7 @@ const dateDiffDefinition: FunctionDefinition = { defaultMessage: 'Subtracts the `startTimestamp` from the `endTimestamp` and returns the difference in multiples of `unit`.\nIf `startTimestamp` is later than the `endTimestamp`, negative values are returned.', }), + preview: false, alias: undefined, signatures: [ { @@ -1305,6 +1319,7 @@ const dateExtractDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.date_extract', { defaultMessage: 'Extracts parts of a date, like year, month, day, hour.', }), + preview: false, alias: undefined, signatures: [ { @@ -1386,6 +1401,7 @@ const dateFormatDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.date_format', { defaultMessage: 'Returns a string representation of a date, in the provided format.', }), + preview: false, alias: undefined, signatures: [ { @@ -1435,6 +1451,7 @@ const dateParseDefinition: FunctionDefinition = { defaultMessage: 'Returns a date by parsing the second argument using the format specified in the first argument.', }), + preview: false, alias: undefined, signatures: [ { @@ -1511,6 +1528,7 @@ const dateTruncDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.date_trunc', { defaultMessage: 'Rounds down a date to the closest interval.', }), + preview: false, alias: undefined, signatures: [ { @@ -1561,6 +1579,7 @@ const eDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.e', { defaultMessage: "Returns Euler's number.", }), + preview: false, alias: undefined, signatures: [ { @@ -1582,6 +1601,7 @@ const endsWithDefinition: FunctionDefinition = { defaultMessage: 'Returns a boolean that indicates whether a keyword string ends with another string.', }), + preview: false, alias: undefined, signatures: [ { @@ -1658,6 +1678,7 @@ const expDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.exp', { defaultMessage: 'Returns the value of e raised to the power of the given number.', }), + preview: false, alias: undefined, signatures: [ { @@ -1714,6 +1735,7 @@ const floorDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.floor', { defaultMessage: 'Round a number down to the nearest integer.', }), + preview: false, alias: undefined, signatures: [ { @@ -1770,6 +1792,7 @@ const fromBase64Definition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.from_base64', { defaultMessage: 'Decode a base64 string.', }), + preview: false, alias: undefined, signatures: [ { @@ -1807,6 +1830,7 @@ const greatestDefinition: FunctionDefinition = { defaultMessage: 'Returns the maximum value from multiple columns. This is similar to `MV_MAX`\nexcept it is intended to run on multiple columns at once.', }), + preview: false, alias: undefined, signatures: [ { @@ -2023,6 +2047,7 @@ const hypotDefinition: FunctionDefinition = { defaultMessage: 'Returns the hypotenuse of two numbers. The input can be any numeric values, the return value is always a double.\nHypotenuses of infinities are null.', }), + preview: false, alias: undefined, signatures: [ { @@ -2279,6 +2304,7 @@ const ipPrefixDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.ip_prefix', { defaultMessage: 'Truncates an IP to a given prefix length.', }), + preview: false, alias: undefined, signatures: [ { @@ -2318,6 +2344,7 @@ const leastDefinition: FunctionDefinition = { defaultMessage: 'Returns the minimum value from multiple columns. This is similar to `MV_MIN` except it is intended to run on multiple columns at once.', }), + preview: false, alias: undefined, signatures: [ { @@ -2534,6 +2561,7 @@ const leftDefinition: FunctionDefinition = { defaultMessage: "Returns the substring that extracts 'length' chars from 'string' starting from the left.", }), + preview: false, alias: undefined, signatures: [ { @@ -2582,6 +2610,7 @@ const lengthDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.length', { defaultMessage: 'Returns the character length of a string.', }), + preview: false, alias: undefined, signatures: [ { @@ -2619,6 +2648,7 @@ const locateDefinition: FunctionDefinition = { defaultMessage: 'Returns an integer that indicates the position of a keyword substring within another string.\nReturns `0` if the substring cannot be found.\nNote that string positions start from `1`.', }), + preview: false, alias: undefined, signatures: [ { @@ -2776,6 +2806,7 @@ const logDefinition: FunctionDefinition = { defaultMessage: 'Returns the logarithm of a value to a base. The input can be any numeric value, the return value is always a double.\n\nLogs of zero, negative numbers, and base of one return `null` as well as a warning.', }), + preview: false, alias: undefined, signatures: [ { @@ -3099,6 +3130,7 @@ const log10Definition: FunctionDefinition = { defaultMessage: 'Returns the logarithm of a value to base 10. The input can be any numeric value, the return value is always a double.\n\nLogs of 0 and negative numbers return `null` as well as a warning.', }), + preview: false, alias: undefined, signatures: [ { @@ -3178,6 +3210,7 @@ const ltrimDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.ltrim', { defaultMessage: 'Removes leading whitespaces from a string.', }), + preview: false, alias: undefined, signatures: [ { @@ -3217,6 +3250,7 @@ const matchDefinition: FunctionDefinition = { defaultMessage: 'Performs a match query on the specified field. Returns true if the provided query matches the row.', }), + preview: true, alias: undefined, signatures: [ { @@ -3295,6 +3329,7 @@ const mvAppendDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.mv_append', { defaultMessage: 'Concatenates values of two multi-value fields.', }), + preview: false, alias: undefined, signatures: [ { @@ -3507,6 +3542,7 @@ const mvAvgDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalued field into a single valued field containing the average of all of the values.', }), + preview: false, alias: undefined, signatures: [ { @@ -3564,6 +3600,7 @@ const mvConcatDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalued string expression into a single valued column containing the concatenation of all values separated by a delimiter.', }), + preview: false, alias: undefined, signatures: [ { @@ -3644,6 +3681,7 @@ const mvCountDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalued expression into a single valued column containing a count of the number of values.', }), + preview: false, alias: undefined, signatures: [ { @@ -3800,6 +3838,7 @@ const mvDedupeDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.mv_dedupe', { defaultMessage: 'Remove duplicate values from a multivalued field.', }), + preview: false, alias: undefined, signatures: [ { @@ -3947,6 +3986,7 @@ const mvFirstDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalued expression into a single valued column containing the\nfirst value. This is most useful when reading from a function that emits\nmultivalued columns in a known order like `SPLIT`.', }), + preview: false, alias: undefined, signatures: [ { @@ -4104,6 +4144,7 @@ const mvLastDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalue expression into a single valued column containing the last\nvalue. This is most useful when reading from a function that emits multivalued\ncolumns in a known order like `SPLIT`.', }), + preview: false, alias: undefined, signatures: [ { @@ -4261,6 +4302,7 @@ const mvMaxDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalued expression into a single valued column containing the maximum value.', }), + preview: false, alias: undefined, signatures: [ { @@ -4381,6 +4423,7 @@ const mvMedianDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalued field into a single valued field containing the median value.', }), + preview: false, alias: undefined, signatures: [ { @@ -4444,6 +4487,7 @@ const mvMedianAbsoluteDeviationDefinition: FunctionDefinition = { "Converts a multivalued field into a single valued field containing the median absolute deviation.\n\nIt is calculated as the median of each data point's deviation from the median of the entire sample. That is, for a random variable `X`, the median absolute deviation is `median(|median(X) - X|)`.", } ), + preview: false, alias: undefined, signatures: [ { @@ -4503,6 +4547,7 @@ const mvMinDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalued expression into a single valued column containing the minimum value.', }), + preview: false, alias: undefined, signatures: [ { @@ -4623,6 +4668,7 @@ const mvPercentileDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalued field into a single valued field containing the value at which a certain percentage of observed values occur.', }), + preview: false, alias: undefined, signatures: [ { @@ -4780,6 +4826,7 @@ const mvPseriesWeightedSumDefinition: FunctionDefinition = { 'Converts a multivalued expression into a single-valued column by multiplying every element on the input list by its corresponding term in P-Series and computing the sum.', } ), + preview: false, alias: undefined, signatures: [ { @@ -4814,6 +4861,7 @@ const mvSliceDefinition: FunctionDefinition = { defaultMessage: 'Returns a subset of the multivalued field using the start and end index values.\nThis is most useful when reading from a function that emits multivalued columns\nin a known order like `SPLIT` or `MV_SORT`.', }), + preview: false, alias: undefined, signatures: [ { @@ -5093,6 +5141,7 @@ const mvSortDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.mv_sort', { defaultMessage: 'Sorts a multivalued field in lexicographical order.', }), + preview: false, alias: undefined, signatures: [ { @@ -5254,6 +5303,7 @@ const mvSumDefinition: FunctionDefinition = { defaultMessage: 'Converts a multivalued field into a single valued field containing the sum of all of the values.', }), + preview: false, alias: undefined, signatures: [ { @@ -5311,6 +5361,7 @@ const mvZipDefinition: FunctionDefinition = { defaultMessage: 'Combines the values from two multivalued fields with a delimiter that joins them together.', }), + preview: false, alias: undefined, signatures: [ { @@ -5549,6 +5600,7 @@ const nowDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.now', { defaultMessage: 'Returns current date and time.', }), + preview: false, alias: undefined, signatures: [ { @@ -5569,6 +5621,7 @@ const piDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.pi', { defaultMessage: "Returns Pi, the ratio of a circle's circumference to its diameter.", }), + preview: false, alias: undefined, signatures: [ { @@ -5589,6 +5642,7 @@ const powDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.pow', { defaultMessage: 'Returns the value of `base` raised to the power of `exponent`.', }), + preview: false, alias: undefined, signatures: [ { @@ -5849,6 +5903,7 @@ const qstrDefinition: FunctionDefinition = { defaultMessage: 'Performs a query string query. Returns true if the provided query string matches the row.', }), + preview: true, alias: undefined, signatures: [ { @@ -5888,6 +5943,7 @@ const repeatDefinition: FunctionDefinition = { defaultMessage: 'Returns a string constructed by concatenating `string` with itself the specified `number` of times.', }), + preview: false, alias: undefined, signatures: [ { @@ -5924,7 +5980,7 @@ const repeatDefinition: FunctionDefinition = { supportedCommands: ['stats', 'inlinestats', 'metrics', 'eval', 'where', 'row', 'sort'], supportedOptions: ['by'], validate: undefined, - examples: ['ROW a = "Hello!"\n| EVAL triple_a = REPEAT(a, 3);'], + examples: ['ROW a = "Hello!"\n| EVAL triple_a = REPEAT(a, 3)'], }; // Do not edit this manually... generated by scripts/generate_function_definitions.ts @@ -5935,6 +5991,7 @@ const replaceDefinition: FunctionDefinition = { defaultMessage: 'The function substitutes in the string `str` any match of the regular expression `regex`\nwith the replacement string `newStr`.', }), + preview: false, alias: undefined, signatures: [ { @@ -6111,6 +6168,7 @@ const reverseDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.reverse', { defaultMessage: 'Returns a new string representing the input string in reverse order.', }), + preview: false, alias: undefined, signatures: [ { @@ -6151,6 +6209,7 @@ const rightDefinition: FunctionDefinition = { defaultMessage: "Return the substring that extracts 'length' chars from 'str' starting from the right.", }), + preview: false, alias: undefined, signatures: [ { @@ -6200,6 +6259,7 @@ const roundDefinition: FunctionDefinition = { defaultMessage: 'Rounds a number to the specified number of decimal places.\nDefaults to 0, which returns the nearest integer. If the\nprecision is a negative number, rounds to the number of digits left\nof the decimal point.', }), + preview: false, alias: undefined, signatures: [ { @@ -6303,6 +6363,7 @@ const rtrimDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.rtrim', { defaultMessage: 'Removes trailing whitespaces from a string.', }), + preview: false, alias: undefined, signatures: [ { @@ -6342,6 +6403,7 @@ const signumDefinition: FunctionDefinition = { defaultMessage: 'Returns the sign of the given number.\nIt returns `-1` for negative numbers, `0` for `0` and `1` for positive numbers.', }), + preview: false, alias: undefined, signatures: [ { @@ -6398,6 +6460,7 @@ const sinDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.sin', { defaultMessage: 'Returns the sine of an angle.', }), + preview: false, alias: undefined, signatures: [ { @@ -6454,6 +6517,7 @@ const sinhDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.sinh', { defaultMessage: 'Returns the hyperbolic sine of a number.', }), + preview: false, alias: undefined, signatures: [ { @@ -6510,6 +6574,7 @@ const spaceDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.space', { defaultMessage: 'Returns a string made of `number` spaces.', }), + preview: false, alias: undefined, signatures: [ { @@ -6536,6 +6601,7 @@ const splitDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.split', { defaultMessage: 'Split a single valued string into multiple strings.', }), + preview: false, alias: undefined, signatures: [ { @@ -6613,6 +6679,7 @@ const sqrtDefinition: FunctionDefinition = { defaultMessage: 'Returns the square root of a number. The input can be any numeric value, the return value is always a double.\nSquare roots of negative numbers and infinities are null.', }), + preview: false, alias: undefined, signatures: [ { @@ -6670,6 +6737,7 @@ const stContainsDefinition: FunctionDefinition = { defaultMessage: 'Returns whether the first geometry contains the second geometry.\nThis is the inverse of the `ST_WITHIN` function.', }), + preview: false, alias: undefined, signatures: [ { @@ -6809,6 +6877,7 @@ const stDisjointDefinition: FunctionDefinition = { defaultMessage: 'Returns whether the two geometries or geometry columns are disjoint.\nThis is the inverse of the `ST_INTERSECTS` function.\nIn mathematical terms: ST_Disjoint(A, B) ⇔ A ⋂ B = ∅', }), + preview: false, alias: undefined, signatures: [ { @@ -6948,6 +7017,7 @@ const stDistanceDefinition: FunctionDefinition = { defaultMessage: 'Computes the distance between two points.\nFor cartesian geometries, this is the pythagorean distance in the same units as the original coordinates.\nFor geographic geometries, this is the circular distance along the great circle in meters.', }), + preview: false, alias: undefined, signatures: [ { @@ -6997,6 +7067,7 @@ const stIntersectsDefinition: FunctionDefinition = { defaultMessage: 'Returns true if two geometries intersect.\nThey intersect if they have any point in common, including their interior points\n(points along lines or within polygons).\nThis is the inverse of the `ST_DISJOINT` function.\nIn mathematical terms: ST_Intersects(A, B) ⇔ A ⋂ B ≠ ∅', }), + preview: false, alias: undefined, signatures: [ { @@ -7136,6 +7207,7 @@ const stWithinDefinition: FunctionDefinition = { defaultMessage: 'Returns whether the first geometry is within the second geometry.\nThis is the inverse of the `ST_CONTAINS` function.', }), + preview: false, alias: undefined, signatures: [ { @@ -7275,6 +7347,7 @@ const stXDefinition: FunctionDefinition = { defaultMessage: 'Extracts the `x` coordinate from the supplied point.\nIf the points is of type `geo_point` this is equivalent to extracting the `longitude` value.', }), + preview: false, alias: undefined, signatures: [ { @@ -7314,6 +7387,7 @@ const stYDefinition: FunctionDefinition = { defaultMessage: 'Extracts the `y` coordinate from the supplied point.\nIf the points is of type `geo_point` this is equivalent to extracting the `latitude` value.', }), + preview: false, alias: undefined, signatures: [ { @@ -7353,6 +7427,7 @@ const startsWithDefinition: FunctionDefinition = { defaultMessage: 'Returns a boolean that indicates whether a keyword string starts with another string.', }), + preview: false, alias: undefined, signatures: [ { @@ -7430,6 +7505,7 @@ const substringDefinition: FunctionDefinition = { defaultMessage: 'Returns a substring of a string, specified by a start position and an optional length.', }), + preview: false, alias: undefined, signatures: [ { @@ -7490,6 +7566,7 @@ const tanDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.tan', { defaultMessage: 'Returns the tangent of an angle.', }), + preview: false, alias: undefined, signatures: [ { @@ -7546,6 +7623,7 @@ const tanhDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.tanh', { defaultMessage: 'Returns the hyperbolic tangent of a number.', }), + preview: false, alias: undefined, signatures: [ { @@ -7602,6 +7680,7 @@ const tauDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.tau', { defaultMessage: "Returns the ratio of a circle's circumference to its radius.", }), + preview: false, alias: undefined, signatures: [ { @@ -7622,6 +7701,7 @@ const toBase64Definition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_base64', { defaultMessage: 'Encode a string to a base64 string.', }), + preview: false, alias: undefined, signatures: [ { @@ -7659,6 +7739,7 @@ const toBooleanDefinition: FunctionDefinition = { defaultMessage: 'Converts an input value to a boolean value.\nA string value of *true* will be case-insensitive converted to the Boolean *true*.\nFor anything else, including the empty string, the function will return *false*.\nThe numerical value of *0* will be converted to *false*, anything else will be converted to *true*.', }), + preview: false, alias: ['to_bool'], signatures: [ { @@ -7749,6 +7830,7 @@ const toCartesianpointDefinition: FunctionDefinition = { 'Converts an input value to a `cartesian_point` value.\nA string will only be successfully converted if it respects WKT Point format.', } ), + preview: false, alias: undefined, signatures: [ { @@ -7801,6 +7883,7 @@ const toCartesianshapeDefinition: FunctionDefinition = { 'Converts an input value to a `cartesian_shape` value.\nA string will only be successfully converted if it respects WKT format.', } ), + preview: false, alias: undefined, signatures: [ { @@ -7859,6 +7942,7 @@ const toDateNanosDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_date_nanos', { defaultMessage: 'Converts an input to a nanosecond-resolution date value (aka date_nanos).', }), + preview: true, alias: undefined, signatures: [], supportedCommands: ['stats', 'inlinestats', 'metrics', 'eval', 'where', 'row', 'sort'], @@ -7874,6 +7958,7 @@ const toDateperiodDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_dateperiod', { defaultMessage: 'Converts an input value into a `date_period` value.', }), + preview: false, alias: undefined, signatures: [ { @@ -7923,6 +8008,7 @@ const toDatetimeDefinition: FunctionDefinition = { defaultMessage: "Converts an input value to a date value.\nA string will only be successfully converted if it's respecting the format `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`.\nTo convert dates in other formats, use `DATE_PARSE`.", }), + preview: false, alias: ['to_dt'], signatures: [ { @@ -8012,6 +8098,7 @@ const toDegreesDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_degrees', { defaultMessage: 'Converts a number in radians to degrees.', }), + preview: false, alias: undefined, signatures: [ { @@ -8069,6 +8156,7 @@ const toDoubleDefinition: FunctionDefinition = { defaultMessage: 'Converts an input value to a double value. If the input parameter is of a date type,\nits value will be interpreted as milliseconds since the Unix epoch,\nconverted to double. Boolean *true* will be converted to double *1.0*, *false* to *0.0*.', }), + preview: false, alias: ['to_dbl'], signatures: [ { @@ -8198,6 +8286,7 @@ const toGeopointDefinition: FunctionDefinition = { defaultMessage: 'Converts an input value to a `geo_point` value.\nA string will only be successfully converted if it respects WKT Point format.', }), + preview: false, alias: undefined, signatures: [ { @@ -8245,6 +8334,7 @@ const toGeoshapeDefinition: FunctionDefinition = { defaultMessage: 'Converts an input value to a `geo_shape` value.\nA string will only be successfully converted if it respects WKT format.', }), + preview: false, alias: undefined, signatures: [ { @@ -8304,6 +8394,7 @@ const toIntegerDefinition: FunctionDefinition = { defaultMessage: 'Converts an input value to an integer value.\nIf the input parameter is of a date type, its value will be interpreted as milliseconds\nsince the Unix epoch, converted to integer.\nBoolean *true* will be converted to integer *1*, *false* to *0*.', }), + preview: false, alias: ['to_int'], signatures: [ { @@ -8410,6 +8501,7 @@ const toIpDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_ip', { defaultMessage: 'Converts an input string to an IP value.', }), + preview: false, alias: undefined, signatures: [ { @@ -8459,6 +8551,7 @@ const toLongDefinition: FunctionDefinition = { defaultMessage: 'Converts an input value to a long value. If the input parameter is of a date type,\nits value will be interpreted as milliseconds since the Unix epoch, converted to long.\nBoolean *true* will be converted to long *1*, *false* to *0*.', }), + preview: false, alias: undefined, signatures: [ { @@ -8577,6 +8670,7 @@ const toLowerDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_lower', { defaultMessage: 'Returns a new string representing the input string converted to lower case.', }), + preview: false, alias: undefined, signatures: [ { @@ -8613,6 +8707,7 @@ const toRadiansDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_radians', { defaultMessage: 'Converts a number in degrees to radians.', }), + preview: false, alias: undefined, signatures: [ { @@ -8669,6 +8764,7 @@ const toStringDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_string', { defaultMessage: 'Converts an input value into a string.', }), + preview: false, alias: ['to_str'], signatures: [ { @@ -8825,6 +8921,7 @@ const toTimedurationDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_timeduration', { defaultMessage: 'Converts an input value into a `time_duration` value.', }), + preview: false, alias: undefined, signatures: [ { @@ -8877,6 +8974,7 @@ const toUnsignedLongDefinition: FunctionDefinition = { 'Converts an input value to an unsigned long value. If the input parameter is of a date type,\nits value will be interpreted as milliseconds since the Unix epoch, converted to unsigned long.\nBoolean *true* will be converted to unsigned long *1*, *false* to *0*.', } ), + preview: false, alias: ['to_ul', 'to_ulong'], signatures: [ { @@ -8975,6 +9073,7 @@ const toUpperDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_upper', { defaultMessage: 'Returns a new string representing the input string converted to upper case.', }), + preview: false, alias: undefined, signatures: [ { @@ -9011,6 +9110,7 @@ const toVersionDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.to_version', { defaultMessage: 'Converts an input string to a version value.', }), + preview: false, alias: ['to_ver'], signatures: [ { @@ -9057,6 +9157,7 @@ const trimDefinition: FunctionDefinition = { description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.trim', { defaultMessage: 'Removes leading and trailing whitespaces from a string.', }), + preview: false, alias: undefined, signatures: [ { @@ -9096,6 +9197,7 @@ const caseDefinition: FunctionDefinition = { defaultMessage: 'Accepts pairs of conditions and values. The function returns the value that belongs to the first condition that evaluates to `true`. If the number of arguments is odd, the last argument is the default value which is returned when no condition matches.', }), + preview: false, alias: undefined, signatures: [ { diff --git a/packages/kbn-esql-validation-autocomplete/src/definitions/types.ts b/packages/kbn-esql-validation-autocomplete/src/definitions/types.ts index a86811f535f8b..ba0a50c4a71b9 100644 --- a/packages/kbn-esql-validation-autocomplete/src/definitions/types.ts +++ b/packages/kbn-esql-validation-autocomplete/src/definitions/types.ts @@ -118,6 +118,7 @@ export const isReturnType = (str: string | FunctionParameterType): str is Functi export interface FunctionDefinition { type: 'builtin' | 'agg' | 'eval'; + preview?: boolean; ignoreAsSuggestion?: boolean; name: string; alias?: string[]; From 8a7514f5e2478e8793e54a9de591286a0414ea60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Gonz=C3=A1lez?= Date: Tue, 12 Nov 2024 10:56:52 +0100 Subject: [PATCH 005/105] [Search][Connectors][a11y] Fixing wrong navigation sequence after closing Manual configuration dialog (#199613) ## Summary This PR closes this issue: https://github.com/elastic/kibana/issues/197623 Now we don't close the Popover content when clicking in any of the options listed in order to keep this content visible. And to solve the z-index issue where the Popover were displayed on top of the Flyout we are modifying the Flyout z-index to become exactly the same as the Popover + 1 to overlap this content. Now we keep the same tab index focus we got before opening the Flyout from the Popover options. ![CleanShot 2024-11-11 at 11 38 57](https://github.com/user-attachments/assets/0a1ff5cb-13ff-45ba-8a89-f5ca91ad77ef) --- .../create_connector/components/manual_configuration.tsx | 2 -- .../components/manual_configuration_flyout.tsx | 6 +++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/manual_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/manual_configuration.tsx index 825f47920d256..260486a3ec4c1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/manual_configuration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/manual_configuration.tsx @@ -165,7 +165,6 @@ GET connector-${rawName}/_search onClick={() => { setFlyoutContent('manual_config'); setIsFlyoutVisible(true); - closePopover(); }} > {i18n.translate( @@ -206,7 +205,6 @@ GET connector-${rawName}/_search onClick={() => { setFlyoutContent('client'); setIsFlyoutVisible(true); - closePopover(); }} > {i18n.translate( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/manual_configuration_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/manual_configuration_flyout.tsx index 98bea7ed62f70..03a633a5aa04f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/manual_configuration_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/create_connector/components/manual_configuration_flyout.tsx @@ -27,6 +27,7 @@ import { EuiSpacer, EuiText, EuiTitle, + useEuiTheme, useGeneratedHtmlId, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -68,13 +69,16 @@ export const ManualConfigurationFlyout: React.FC const { connectorName } = useValues(NewConnectorLogic); const { setRawName, createConnector } = useActions(NewConnectorLogic); - + const { euiTheme } = useEuiTheme(); return ( setIsFlyoutVisible(false)} aria-labelledby={simpleFlyoutTitleId} size="s" + // This fixes an a11y issue where the flyout was rendered below the Popover + // Now we let get the focus back to the Popover is we close the Flyout + maskProps={{ style: `z-index: ${Number(euiTheme.levels.menu) + 1}` }} > {flyoutContent === 'manual_config' && ( <> From fa6d8ee9e0f6fcaa0280fbf5ab60217f9f28279f Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 12 Nov 2024 10:02:26 +0000 Subject: [PATCH 006/105] [ML] File upload adding deployment initialization step (#198446) Fixes https://github.com/elastic/kibana/issues/196696 When adding a semantic text field, we now have an additional step in the file uploading process which calls inference for the selected inference endpoint. The response of the inference call is ignored and a poll is started to check to see of the model has been deployed by check to see if `num_allocations > 0` Any errors returned from the inference call will stop the upload, unless they are timeout errors which are ignored. https://github.com/user-attachments/assets/382ce565-3b4b-47a3-a081-d79c15aa462f --- .../file_data_visualizer_view.js | 3 - .../import_progress/import_progress.tsx | 136 +++++++++++++----- .../components/import_view/auto_deploy.ts | 76 ++++++++++ .../components/import_view/import.ts | 57 ++++++-- .../components/import_view/import_view.js | 26 +++- .../file_data_visualizer.tsx | 1 - .../plugins/data_visualizer/server/routes.ts | 50 ++++++- 7 files changed, 291 insertions(+), 58 deletions(-) create mode 100644 x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/auto_deploy.ts diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_data_visualizer_view/file_data_visualizer_view.js b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_data_visualizer_view/file_data_visualizer_view.js index e19b2cbceda33..676830e94a280 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_data_visualizer_view/file_data_visualizer_view.js +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_data_visualizer_view/file_data_visualizer_view.js @@ -360,9 +360,6 @@ export class FileDataVisualizerView extends Component { fileName={fileName} fileContents={fileContents} data={data} - dataViewsContract={this.props.dataViewsContract} - dataStart={this.props.dataStart} - fileUpload={this.props.fileUpload} getAdditionalLinks={this.props.getAdditionalLinks} resultLinks={this.props.resultLinks} capabilities={this.props.capabilities} diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_progress/import_progress.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_progress/import_progress.tsx index 53b92ab1f6414..5a6db4f544fd9 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_progress/import_progress.tsx +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_progress/import_progress.tsx @@ -31,6 +31,8 @@ export interface Statuses { createDataView: boolean; createPipeline: boolean; permissionCheckStatus: IMPORT_STATUS; + initializeDeployment: boolean; + initializeDeploymentStatus: IMPORT_STATUS; } export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { @@ -45,6 +47,8 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { uploadStatus, createDataView, createPipeline, + initializeDeployment, + initializeDeploymentStatus, } = statuses; let statusInfo = null; @@ -58,27 +62,37 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { ) { completedStep = 0; } + + if ( + readStatus === IMPORT_STATUS.COMPLETE && + initializeDeployment === true && + initializeDeploymentStatus === IMPORT_STATUS.INCOMPLETE + ) { + completedStep = 1; + } + if ( readStatus === IMPORT_STATUS.COMPLETE && + (initializeDeployment === false || initializeDeploymentStatus === IMPORT_STATUS.COMPLETE) && indexCreatedStatus === IMPORT_STATUS.INCOMPLETE && ingestPipelineCreatedStatus === IMPORT_STATUS.INCOMPLETE ) { - completedStep = 1; + completedStep = 2; } if (indexCreatedStatus === IMPORT_STATUS.COMPLETE) { - completedStep = 2; + completedStep = 3; } if ( ingestPipelineCreatedStatus === IMPORT_STATUS.COMPLETE || (createPipeline === false && indexCreatedStatus === IMPORT_STATUS.COMPLETE) ) { - completedStep = 3; + completedStep = 4; } if (uploadStatus === IMPORT_STATUS.COMPLETE) { - completedStep = 4; + completedStep = 5; } if (dataViewCreatedStatus === IMPORT_STATUS.COMPLETE) { - completedStep = 5; + completedStep = 6; } let processFileTitle = i18n.translate( @@ -87,6 +101,12 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { defaultMessage: 'Process file', } ); + let initializeDeploymentTitle = i18n.translate( + 'xpack.dataVisualizer.file.importProgress.initializeDeploymentTitle', + { + defaultMessage: 'Initialize model deployment', + } + ); let createIndexTitle = i18n.translate( 'xpack.dataVisualizer.file.importProgress.createIndexTitle', { @@ -146,13 +166,43 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => {

); } - if (completedStep >= 1) { + if (initializeDeployment) { + if (completedStep >= 1) { + processFileTitle = i18n.translate( + 'xpack.dataVisualizer.file.importProgress.fileProcessedTitle', + { + defaultMessage: 'File processed', + } + ); + initializeDeploymentTitle = i18n.translate( + 'xpack.dataVisualizer.file.importProgress.initializingDeploymentTitle', + { + defaultMessage: 'Initializing model deployment', + } + ); + statusInfo = ( +

+ +

+ ); + } + } + if (completedStep >= 2) { processFileTitle = i18n.translate( 'xpack.dataVisualizer.file.importProgress.fileProcessedTitle', { defaultMessage: 'File processed', } ); + initializeDeploymentTitle = i18n.translate( + 'xpack.dataVisualizer.file.importProgress.deploymentInitializedTitle', + { + defaultMessage: 'Model deployed', + } + ); createIndexTitle = i18n.translate( 'xpack.dataVisualizer.file.importProgress.creatingIndexTitle', { @@ -162,7 +212,7 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { statusInfo = createPipeline === true ? creatingIndexAndIngestPipelineStatus : creatingIndexStatus; } - if (completedStep >= 2) { + if (completedStep >= 3) { createIndexTitle = i18n.translate( 'xpack.dataVisualizer.file.importProgress.indexCreatedTitle', { @@ -178,7 +228,7 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { statusInfo = createPipeline === true ? creatingIndexAndIngestPipelineStatus : creatingIndexStatus; } - if (completedStep >= 3) { + if (completedStep >= 4) { createIngestPipelineTitle = i18n.translate( 'xpack.dataVisualizer.file.importProgress.ingestPipelineCreatedTitle', { @@ -193,7 +243,7 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { ); statusInfo = ; } - if (completedStep >= 4) { + if (completedStep >= 5) { uploadingDataTitle = i18n.translate( 'xpack.dataVisualizer.file.importProgress.dataUploadedTitle', { @@ -219,7 +269,7 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { statusInfo = null; } } - if (completedStep >= 5) { + if (completedStep >= 6) { createDataViewTitle = i18n.translate( 'xpack.dataVisualizer.file.importProgress.dataViewCreatedTitle', { @@ -239,44 +289,58 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { : 'selected') as EuiStepStatus, onClick: () => {}, }, - { - title: createIndexTitle, - status: (indexCreatedStatus !== IMPORT_STATUS.INCOMPLETE // Show failure/completed states first - ? indexCreatedStatus + ]; + + if (initializeDeployment === true) { + steps.push({ + title: initializeDeploymentTitle, + status: (initializeDeploymentStatus !== IMPORT_STATUS.INCOMPLETE // Show failure/completed states first + ? initializeDeploymentStatus : completedStep === 1 // Then show selected/incomplete states ? 'selected' : 'incomplete') as EuiStepStatus, onClick: () => {}, - }, - { - title: uploadingDataTitle, - status: (uploadStatus !== IMPORT_STATUS.INCOMPLETE // Show failure/completed states first - ? uploadStatus - : completedStep === 3 // Then show selected/incomplete states - ? 'selected' - : 'incomplete') as EuiStepStatus, - onClick: () => {}, - }, - ]; + }); + } + + steps.push({ + title: createIndexTitle, + status: (indexCreatedStatus !== IMPORT_STATUS.INCOMPLETE // Show failure/completed states first + ? indexCreatedStatus + : completedStep === 2 // Then show selected/incomplete states + ? 'selected' + : 'incomplete') as EuiStepStatus, + onClick: () => {}, + }); if (createPipeline === true) { - steps.splice(2, 0, { + steps.push({ title: createIngestPipelineTitle, status: (ingestPipelineCreatedStatus !== IMPORT_STATUS.INCOMPLETE // Show failure/completed states first ? ingestPipelineCreatedStatus - : completedStep === 2 // Then show selected/incomplete states + : completedStep === 3 // Then show selected/incomplete states ? 'selected' : 'incomplete') as EuiStepStatus, onClick: () => {}, }); } + steps.push({ + title: uploadingDataTitle, + status: (uploadStatus !== IMPORT_STATUS.INCOMPLETE // Show failure/completed states first + ? uploadStatus + : completedStep === 4 // Then show selected/incomplete states + ? 'selected' + : 'incomplete') as EuiStepStatus, + onClick: () => {}, + }); + if (createDataView === true) { steps.push({ title: createDataViewTitle, status: (dataViewCreatedStatus !== IMPORT_STATUS.INCOMPLETE // Show failure/completed states first ? dataViewCreatedStatus - : completedStep === 4 // Then show selected/incomplete states + : completedStep === 5 // Then show selected/incomplete states ? 'selected' : 'incomplete') as EuiStepStatus, onClick: () => {}, @@ -284,21 +348,21 @@ export const ImportProgress: FC<{ statuses: Statuses }> = ({ statuses }) => { } return ( - + <> {statusInfo && ( - + <> {statusInfo} - + )} - + ); }; const UploadFunctionProgress: FC<{ progress: number }> = ({ progress }) => { return ( - + <>

= ({ progress }) => { />

{progress < 100 && ( - + <> - + )} -
+ ); }; diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/auto_deploy.ts b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/auto_deploy.ts new file mode 100644 index 0000000000000..a402d203585d2 --- /dev/null +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/auto_deploy.ts @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { InferenceInferenceEndpointInfo } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { HttpSetup } from '@kbn/core/public'; + +const POLL_INTERVAL = 5; // seconds + +export class AutoDeploy { + private inferError: Error | null = null; + constructor(private readonly http: HttpSetup, private readonly inferenceId: string) {} + + public async deploy() { + this.inferError = null; + if (await this.isDeployed()) { + return; + } + + this.infer().catch((e) => { + // ignore timeout errors + // The deployment may take a long time + // we'll know when it's ready from polling the inference endpoints + // looking for num_allocations + const status = e.response?.status; + if (status === 408 || status === 504 || status === 502) { + return; + } + this.inferError = e; + }); + await this.pollIsDeployed(); + } + + private async infer() { + return this.http.fetch( + `/internal/data_visualizer/inference/${this.inferenceId}`, + { + method: 'POST', + version: '1', + body: JSON.stringify({ input: '' }), + } + ); + } + + private async isDeployed() { + const inferenceEndpoints = await this.http.fetch( + '/internal/data_visualizer/inference_endpoints', + { + method: 'GET', + version: '1', + } + ); + return inferenceEndpoints.some((endpoint) => { + return ( + endpoint.inference_id === this.inferenceId && endpoint.service_settings.num_allocations > 0 + ); + }); + } + + private async pollIsDeployed() { + while (true) { + if (this.inferError !== null) { + throw this.inferError; + } + const isDeployed = await this.isDeployed(); + if (isDeployed) { + // break out of the loop once we have a successful deployment + return; + } + await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL * 1000)); + } + } +} diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import.ts b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import.ts index 8611e1ccd2cab..a44cb4fb890fe 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import.ts +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import.ts @@ -12,13 +12,17 @@ import type { } from '@kbn/file-upload-plugin/common/types'; import type { FileUploadStartApi } from '@kbn/file-upload-plugin/public/api'; import { i18n } from '@kbn/i18n'; +import type { HttpSetup } from '@kbn/core/public'; +import type { MappingTypeMapping } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { IMPORT_STATUS } from '../import_progress/import_progress'; +import { AutoDeploy } from './auto_deploy'; interface Props { data: ArrayBuffer; results: FindFileStructureResponse; dataViewsContract: DataViewsServicePublic; fileUpload: FileUploadStartApi; + http: HttpSetup; } interface Config { @@ -33,7 +37,7 @@ interface Config { } export async function importData(props: Props, config: Config, setState: (state: unknown) => void) { - const { data, results, dataViewsContract, fileUpload } = props; + const { data, results, dataViewsContract, fileUpload, http } = props; const { index, dataView, @@ -76,14 +80,6 @@ export async function importData(props: Props, config: Config, setState: (state: return; } - setState({ - importing: true, - imported: false, - reading: true, - initialized: true, - permissionCheckStatus: IMPORT_STATUS.COMPLETE, - }); - let success = true; let settings = {}; @@ -122,7 +118,15 @@ export async function importData(props: Props, config: Config, setState: (state: errors.push(`${parseError} ${error.message}`); } + const inferenceId = getInferenceId(mappings); + setState({ + importing: true, + imported: false, + reading: true, + initialized: true, + permissionCheckStatus: IMPORT_STATUS.COMPLETE, + initializeDeployment: inferenceId !== null, parseJSONStatus: getSuccess(success), }); @@ -147,6 +151,32 @@ export async function importData(props: Props, config: Config, setState: (state: return; } + if (inferenceId) { + // Initialize deployment + const autoDeploy = new AutoDeploy(http, inferenceId); + + try { + await autoDeploy.deploy(); + setState({ + initializeDeploymentStatus: IMPORT_STATUS.COMPLETE, + }); + } catch (error) { + success = false; + const deployError = i18n.translate('xpack.dataVisualizer.file.importView.deployModelError', { + defaultMessage: 'Error deploying trained model:', + }); + errors.push(`${deployError} ${error.message}`); + setState({ + initializeDeploymentStatus: IMPORT_STATUS.FAILED, + errors, + }); + } + } + + if (success === false) { + return; + } + const initializeImportResp = await importer.initializeImport(index, settings, mappings, pipeline); const timeFieldName = importer.getTimeField(); @@ -245,3 +275,12 @@ async function createKibanaDataView( function getSuccess(success: boolean) { return success ? IMPORT_STATUS.COMPLETE : IMPORT_STATUS.FAILED; } + +function getInferenceId(mappings: MappingTypeMapping) { + for (const value of Object.values(mappings.properties ?? {})) { + if (value.type === 'semantic_text') { + return value.inference_id; + } + } + return null; +} diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import_view.js b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import_view.js index 8481ed76e5654..3f30062270060 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import_view.js +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import_view.js @@ -21,6 +21,7 @@ import { } from '@elastic/eui'; import { debounce } from 'lodash'; +import { context } from '@kbn/kibana-react-plugin/public'; import { ResultsLinks } from '../../../common/components/results_links'; import { FilebeatConfigFlyout } from '../../../common/components/filebeat_config_flyout'; import { ImportProgress, IMPORT_STATUS } from '../import_progress'; @@ -76,14 +77,17 @@ const DEFAULT_STATE = { combinedFields: [], importer: undefined, createPipeline: true, + initializeDeployment: false, + initializeDeploymentStatus: IMPORT_STATUS.INCOMPLETE, }; export class ImportView extends Component { + static contextType = context; + constructor(props) { super(props); this.state = getDefaultState(DEFAULT_STATE, this.props.results, this.props.capabilities); - this.dataViewsContract = props.dataViewsContract; } componentDidMount() { @@ -98,7 +102,12 @@ export class ImportView extends Component { }; clickImport = () => { - const { data, results, dataViewsContract, fileUpload } = this.props; + const { data, results } = this.props; + const { + data: { dataViews: dataViewsContract }, + fileUpload, + http, + } = this.context.services; const { index, dataView, @@ -110,12 +119,13 @@ export class ImportView extends Component { } = this.state; const createPipeline = pipelineString !== ''; + this.setState({ createPipeline, }); importData( - { data, results, dataViewsContract, fileUpload }, + { data, results, dataViewsContract, fileUpload, http }, { index, dataView, @@ -150,7 +160,7 @@ export class ImportView extends Component { return; } - const exists = await this.props.fileUpload.checkIndexExists(index); + const exists = await this.context.services.fileUpload.checkIndexExists(index); const indexNameError = exists ? ( )} diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx index 01d9d2c37194f..6289a73e2a664 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx @@ -44,7 +44,6 @@ export const FileDataVisualizer: FC = ({ getAdditionalLinks, resultLinks , logger: Logger) const filteredInferenceEndpoints = endpoints.filter((endpoint) => { return ( - (endpoint.task_type === 'sparse_embedding' || - endpoint.task_type === 'text_embedding') && - endpoint.service_settings.num_allocations >= 0 + endpoint.task_type === 'sparse_embedding' || endpoint.task_type === 'text_embedding' ); }); @@ -108,4 +106,50 @@ export function routes(coreSetup: CoreSetup, logger: Logger) } } ); + + /** + * @apiGroup DataVisualizer + * + * @api {get} /internal/data_visualizer/inference/{inferenceId} Runs inference on a given inference endpoint with the provided input + * @apiName inference + * @apiDescription Runs inference on a given inference endpoint with the provided input. + */ + router.versioned + .post({ + path: '/internal/data_visualizer/inference/{inferenceId}', + access: 'internal', + options: { + tags: ['access:fileUpload:analyzeFile'], + }, + }) + .addVersion( + { + version: '1', + validate: { + request: { + params: schema.object({ + inferenceId: schema.string(), + }), + body: schema.object({ + input: schema.string(), + }), + }, + }, + }, + async (context, request, response) => { + try { + const inferenceId = request.params.inferenceId; + const input = request.body.input; + const esClient = (await context.core).elasticsearch.client; + const body = await esClient.asCurrentUser.inference.inference({ + inference_id: inferenceId, + input, + }); + + return response.ok({ body }); + } catch (e) { + return response.customError(wrapError(e)); + } + } + ); } From 3d3b32faf6992f95805a37230e7e7e552e19a801 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Tue, 12 Nov 2024 11:04:10 +0100 Subject: [PATCH 007/105] [Security Solution] `FinalEdit`: Add fields that are common for all rule types (#196642) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Partially addresses: https://github.com/elastic/kibana/issues/171520** **Is a follow-up to: https://github.com/elastic/kibana/pull/196326** This PR enables editing of common fields in the new "Updates" tab of the rule upgrade flyout. The common fields are fields applicable to all rule types. ## Summary These fields are editable now: - `building_block` - `description` - `false_positives` - `investigation_fields` - `max_signals` - `note` - `references` - `related_integrations` - `required_fields` - `risk_score` - `risk_score_mapping` - `rule_name_override` - `rule_schedule` - `setup` - `severity` - `severity_mapping` - `tags` - `threat` - `timeline_template` - `timestamp_override` Scherm­afbeelding 2024-10-16 om 17 32 06 ### Testing - Ensure the `prebuiltRulesCustomizationEnabled` feature flag is enabled. - To simulate the availability of prebuilt rule upgrades, downgrade a currently installed prebuilt rule using the `PATCH api/detection_engine/rules` API. - Set `version: 1` in the request body to downgrade it to version 1. - Modify other rule fields in the request body as needed to test the changes. --- .../index.ts | 2 +- .../__snapshots__/index.test.tsx.snap | 0 .../disabled_types_with_tooltip_text.test.ts | 0 .../__tests__/index.test.tsx | 14 +- .../__tests__/use_es_field.test.ts} | 34 +-- .../disabled_types_with_tooltip_text.ts | 0 .../{field => es_field_selector}/index.tsx | 25 +- .../src/{field => es_field_selector}/types.ts | 9 - .../use_es_field.tsx} | 2 +- .../src/field_value_match/index.tsx | 8 +- .../components/builder/entry_renderer.tsx | 4 +- .../components/threat_match/entry_item.tsx | 6 +- .../make_validate_required_field.ts | 25 +- .../required_fields/required_fields.tsx | 8 +- .../required_fields/required_fields_row.tsx | 8 - .../components/required_fields/utils.ts | 25 ++ .../index.tsx | 34 +-- .../components/max_signals/index.tsx | 20 +- .../components/max_signals/translations.ts | 7 - .../risk_score_mapping/default_risk_score.tsx | 77 ++++++ .../components/risk_score_mapping/index.tsx | 210 +++------------- .../risk_score_override.tsx | 163 ++++++++++++ .../severity_mapping/default_severity.tsx | 60 +++++ .../components/severity_mapping/index.tsx | 233 ++--------------- .../severity_mapping/severity_override.tsx | 234 ++++++++++++++++++ .../components/severity_mapping/styles.ts | 24 ++ .../components/step_about_rule/index.tsx | 11 +- .../components/step_about_rule/schema.tsx | 31 ++- .../step_define_rule/index.test.tsx | 4 +- .../pages/rule_creation/helpers.ts | 25 +- .../default_risk_score_validator.ts | 30 +++ .../max_signals_validator_factory.ts | 26 ++ .../final_edit/common_rule_field_edit.tsx | 233 ++++++++++++++++- .../final_edit/fields/building_block.tsx | 32 +++ .../final_edit/fields/description.tsx | 27 ++ .../final_edit/fields/false_positives.tsx | 44 ++++ .../fields/investigation_fields.tsx | 82 ++++++ .../final_edit/fields/max_signals.tsx | 42 ++++ .../three_way_diff/final_edit/fields/name.tsx | 18 +- .../three_way_diff/final_edit/fields/note.tsx | 26 ++ .../final_edit/fields/references.tsx | 38 +++ .../fields/related_integrations.tsx | 39 +++ .../final_edit/fields/required_fields.tsx | 61 +++++ .../final_edit/fields/risk_score.tsx | 57 +++++ .../final_edit/fields/risk_score_mapping.tsx | 106 ++++++++ .../fields/rule_field_edit_form_wrapper.tsx | 4 +- .../final_edit/fields/rule_name_override.tsx | 71 ++++++ .../final_edit/fields/rule_schedule.tsx | 56 +++++ .../final_edit/fields/setup.tsx | 27 ++ .../final_edit/fields/severity.tsx | 25 ++ .../final_edit/fields/severity_mapping.tsx | 149 +++++++++++ .../three_way_diff/final_edit/fields/tags.tsx | 25 ++ .../final_edit/fields/threat.tsx | 30 +++ .../final_edit/fields/timeline_template.tsx | 48 ++++ .../final_edit/fields/timestamp_override.tsx | 95 +++++++ .../three_way_diff/final_edit/utils.ts | 41 +++ .../common_rule_field_readonly.tsx | 2 +- .../fields/building_block/building_block.tsx | 11 +- .../false_positives/false_positives.tsx | 4 + .../final_readonly/fields/note/note.tsx | 4 + .../fields/references/references.tsx | 4 + .../related_integrations.tsx | 4 + .../final_readonly/fields/setup/setup.tsx | 4 + .../final_readonly/fields/tags/tags.tsx | 4 + .../final_readonly/fields/threat/threat.tsx | 4 + .../pages/detection_engine/rules/utils.ts | 3 +- .../translations/translations/fr-FR.json | 1 - .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 69 files changed, 2248 insertions(+), 534 deletions(-) rename packages/kbn-securitysolution-autocomplete/src/{field => es_field_selector}/__tests__/__snapshots__/index.test.tsx.snap (100%) rename packages/kbn-securitysolution-autocomplete/src/{field => es_field_selector}/__tests__/disabled_types_with_tooltip_text.test.ts (100%) rename packages/kbn-securitysolution-autocomplete/src/{field => es_field_selector}/__tests__/index.test.tsx (96%) rename packages/kbn-securitysolution-autocomplete/src/{field/__tests__/use_field.test.ts => es_field_selector/__tests__/use_es_field.test.ts} (91%) rename packages/kbn-securitysolution-autocomplete/src/{field => es_field_selector}/disabled_types_with_tooltip_text.ts (100%) rename packages/kbn-securitysolution-autocomplete/src/{field => es_field_selector}/index.tsx (85%) rename packages/kbn-securitysolution-autocomplete/src/{field => es_field_selector}/types.ts (85%) rename packages/kbn-securitysolution-autocomplete/src/{field/use_field.tsx => es_field_selector/use_es_field.tsx} (99%) rename x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/{autocomplete_field => es_field_selector_field}/index.tsx (70%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/default_risk_score.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/risk_score_override.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/severity_override.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/styles.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/validators/default_risk_score_validator.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/validators/max_signals_validator_factory.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/building_block.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/description.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/false_positives.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/investigation_fields.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/max_signals.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/note.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/references.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/related_integrations.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/required_fields.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/risk_score.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/risk_score_mapping.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_name_override.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/setup.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/severity.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/severity_mapping.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/tags.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threat.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/timeline_template.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/timestamp_override.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/utils.ts diff --git a/packages/kbn-securitysolution-autocomplete/index.ts b/packages/kbn-securitysolution-autocomplete/index.ts index fef857773701c..e47113719176f 100644 --- a/packages/kbn-securitysolution-autocomplete/index.ts +++ b/packages/kbn-securitysolution-autocomplete/index.ts @@ -8,7 +8,7 @@ */ export * from './src/check_empty_value'; -export * from './src/field'; +export * from './src/es_field_selector'; export * from './src/field_value_exists'; export * from './src/field_value_lists'; export * from './src/field_value_match'; diff --git a/packages/kbn-securitysolution-autocomplete/src/field/__tests__/__snapshots__/index.test.tsx.snap b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/__tests__/__snapshots__/index.test.tsx.snap similarity index 100% rename from packages/kbn-securitysolution-autocomplete/src/field/__tests__/__snapshots__/index.test.tsx.snap rename to packages/kbn-securitysolution-autocomplete/src/es_field_selector/__tests__/__snapshots__/index.test.tsx.snap diff --git a/packages/kbn-securitysolution-autocomplete/src/field/__tests__/disabled_types_with_tooltip_text.test.ts b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/__tests__/disabled_types_with_tooltip_text.test.ts similarity index 100% rename from packages/kbn-securitysolution-autocomplete/src/field/__tests__/disabled_types_with_tooltip_text.test.ts rename to packages/kbn-securitysolution-autocomplete/src/es_field_selector/__tests__/disabled_types_with_tooltip_text.test.ts diff --git a/packages/kbn-securitysolution-autocomplete/src/field/__tests__/index.test.tsx b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/__tests__/index.test.tsx similarity index 96% rename from packages/kbn-securitysolution-autocomplete/src/field/__tests__/index.test.tsx rename to packages/kbn-securitysolution-autocomplete/src/es_field_selector/__tests__/index.test.tsx index b795abc5842f2..1b33b4b294644 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field/__tests__/index.test.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/__tests__/index.test.tsx @@ -11,13 +11,13 @@ import React from 'react'; import { fireEvent, render, waitFor, within } from '@testing-library/react'; import '@testing-library/jest-dom'; -import { FieldComponent } from '..'; +import { EsFieldSelector } from '..'; import { fields, getField } from '../../fields/index.mock'; describe('FieldComponent', () => { it('should render the component enabled and displays the selected field correctly', () => { const wrapper = render( - { }); it('should render the component disabled if isDisabled is true', () => { const wrapper = render( - { }); it('should render the loading spinner if isLoading is true when clicked', () => { const wrapper = render( - { }); it('should allow user to clear values if isClearable is true', () => { const wrapper = render( - { }); it('should change the selected value', async () => { const wrapper = render( - { it('it allows custom user input if "acceptsCustomOptions" is "true"', async () => { const mockOnChange = jest.fn(); const wrapper = render( - ({ BINARY_TYPE_NOT_SUPPORTED: 'Binary fields are currently unsupported', @@ -33,7 +33,7 @@ describe('useField', () => { describe('comboOptions and selectedComboOptions', () => { it('should return default values', () => { - const { result } = renderHook(() => useField({ indexPattern, onChange: onChangeMock })); + const { result } = renderHook(() => useEsField({ indexPattern, onChange: onChangeMock })); const { isInvalid, comboOptions, selectedComboOptions, fieldWidth } = result.current; expect(isInvalid).toBeFalsy(); expect(comboOptions.length).toEqual(30); @@ -79,7 +79,7 @@ describe('useField', () => { }; const { result } = renderHook(() => - useField({ indexPattern: newIndexPattern, onChange: onChangeMock }) + useEsField({ indexPattern: newIndexPattern, onChange: onChangeMock }) ); const { comboOptions, selectedComboOptions } = result.current; expect(comboOptions).toEqual([{ label: 'bytes' }, { label: 'ssl' }, { label: '@timestamp' }]); @@ -124,7 +124,7 @@ describe('useField', () => { }; const { result } = renderHook(() => - useField({ + useEsField({ indexPattern: newIndexPattern, onChange: onChangeMock, selectedField: { name: '', type: 'keyword' }, @@ -173,7 +173,7 @@ describe('useField', () => { }; const { result } = renderHook(() => - useField({ + useEsField({ indexPattern: newIndexPattern, onChange: onChangeMock, selectedField: { name: ' ', type: 'keyword' }, @@ -222,7 +222,7 @@ describe('useField', () => { }; const { result } = renderHook(() => - useField({ indexPattern: newIndexPattern, onChange: onChangeMock, selectedField }) + useEsField({ indexPattern: newIndexPattern, onChange: onChangeMock, selectedField }) ); const { comboOptions, selectedComboOptions } = result.current; expect(comboOptions).toEqual([{ label: 'bytes' }, { label: 'ssl' }, { label: '@timestamp' }]); @@ -273,7 +273,7 @@ describe('useField', () => { readFromDocValues: true, }, ] as unknown as DataViewFieldBase[]; - const { result } = renderHook(() => useField({ indexPattern, onChange: onChangeMock })); + const { result } = renderHook(() => useEsField({ indexPattern, onChange: onChangeMock })); const { comboOptions, renderFields } = result.current; expect(comboOptions).toEqual([ { label: 'blob' }, @@ -328,7 +328,7 @@ describe('useField', () => { readFromDocValues: true, }, ] as unknown as DataViewFieldBase[]; - const { result } = renderHook(() => useField({ indexPattern, onChange: onChangeMock })); + const { result } = renderHook(() => useEsField({ indexPattern, onChange: onChangeMock })); const { comboOptions, renderFields } = result.current; expect(comboOptions).toEqual([ { label: 'blob' }, @@ -374,7 +374,7 @@ describe('useField', () => { readFromDocValues: true, }, ] as unknown as DataViewFieldBase[]; - const { result } = renderHook(() => useField({ indexPattern, onChange: onChangeMock })); + const { result } = renderHook(() => useEsField({ indexPattern, onChange: onChangeMock })); const { comboOptions, renderFields } = result.current; expect(comboOptions).toEqual([{ label: 'bytes' }, { label: 'ssl' }, { label: '@timestamp' }]); act(() => { @@ -389,7 +389,7 @@ describe('useField', () => { jest.resetModules(); }); it('should invoke onChange with one value if one option is sent', () => { - const { result } = renderHook(() => useField({ indexPattern, onChange: onChangeMock })); + const { result } = renderHook(() => useEsField({ indexPattern, onChange: onChangeMock })); act(() => { result.current.handleValuesChange([ { @@ -411,7 +411,7 @@ describe('useField', () => { }); }); it('should invoke onChange with array value if more than an option', () => { - const { result } = renderHook(() => useField({ indexPattern, onChange: onChangeMock })); + const { result } = renderHook(() => useEsField({ indexPattern, onChange: onChangeMock })); act(() => { result.current.handleValuesChange([ { @@ -446,7 +446,7 @@ describe('useField', () => { }); }); it('should invoke onChange with custom option if one is sent', () => { - const { result } = renderHook(() => useField({ indexPattern, onChange: onChangeMock })); + const { result } = renderHook(() => useEsField({ indexPattern, onChange: onChangeMock })); act(() => { result.current.handleCreateCustomOption('madeUpField'); expect(onChangeMock).toHaveBeenCalledWith([ @@ -462,13 +462,13 @@ describe('useField', () => { describe('fieldWidth', () => { it('should return object has width prop', () => { const { result } = renderHook(() => - useField({ indexPattern, onChange: onChangeMock, fieldInputWidth: 100 }) + useEsField({ indexPattern, onChange: onChangeMock, fieldInputWidth: 100 }) ); expect(result.current.fieldWidth).toEqual({ width: '100px' }); }); it('should return empty object', () => { const { result } = renderHook(() => - useField({ indexPattern, onChange: onChangeMock, fieldInputWidth: 0 }) + useEsField({ indexPattern, onChange: onChangeMock, fieldInputWidth: 0 }) ); expect(result.current.fieldWidth).toEqual({}); }); @@ -477,7 +477,7 @@ describe('useField', () => { describe('isInvalid with handleTouch', () => { it('should return isInvalid equals true when calling with no selectedField and isRequired is true', () => { const { result } = renderHook(() => - useField({ indexPattern, onChange: onChangeMock, isRequired: true }) + useEsField({ indexPattern, onChange: onChangeMock, isRequired: true }) ); actTestRenderer(() => { @@ -487,7 +487,7 @@ describe('useField', () => { }); it('should return isInvalid equals false with selectedField and isRequired is true', () => { const { result } = renderHook(() => - useField({ indexPattern, onChange: onChangeMock, isRequired: true, selectedField }) + useEsField({ indexPattern, onChange: onChangeMock, isRequired: true, selectedField }) ); actTestRenderer(() => { @@ -496,7 +496,7 @@ describe('useField', () => { expect(result.current.isInvalid).toBeFalsy(); }); it('should return isInvalid equals false when isRequired is false', () => { - const { result } = renderHook(() => useField({ indexPattern, onChange: onChangeMock })); + const { result } = renderHook(() => useEsField({ indexPattern, onChange: onChangeMock })); actTestRenderer(() => { result.current.handleTouch(); diff --git a/packages/kbn-securitysolution-autocomplete/src/field/disabled_types_with_tooltip_text.ts b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/disabled_types_with_tooltip_text.ts similarity index 100% rename from packages/kbn-securitysolution-autocomplete/src/field/disabled_types_with_tooltip_text.ts rename to packages/kbn-securitysolution-autocomplete/src/es_field_selector/disabled_types_with_tooltip_text.ts diff --git a/packages/kbn-securitysolution-autocomplete/src/field/index.tsx b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/index.tsx similarity index 85% rename from packages/kbn-securitysolution-autocomplete/src/field/index.tsx rename to packages/kbn-securitysolution-autocomplete/src/es_field_selector/index.tsx index 7c830264af302..31efaa23b62df 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/index.tsx @@ -11,12 +11,22 @@ import React from 'react'; import { EuiComboBox } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FieldProps } from './types'; -import { useField } from './use_field'; +import { FieldBaseProps } from './types'; +import { useEsField } from './use_es_field'; const AS_PLAIN_TEXT = { asPlainText: true }; -export const FieldComponent: React.FC = ({ +interface EsFieldSelectorProps extends FieldBaseProps { + isClearable?: boolean; + isDisabled?: boolean; + isLoading?: boolean; + placeholder: string; + acceptsCustomOptions?: boolean; + showMappingConflicts?: boolean; + 'aria-label'?: string; +} + +export function EsFieldSelector({ fieldInputWidth, fieldTypeFilter = [], indexPattern, @@ -30,18 +40,17 @@ export const FieldComponent: React.FC = ({ acceptsCustomOptions = false, showMappingConflicts = false, 'aria-label': ariaLabel, -}): JSX.Element => { +}: EsFieldSelectorProps): JSX.Element { const { isInvalid, comboOptions, selectedComboOptions, fieldWidth, - renderFields, handleTouch, handleValuesChange, handleCreateCustomOption, - } = useField({ + } = useEsField({ indexPattern, fieldTypeFilter, isRequired, @@ -97,6 +106,4 @@ export const FieldComponent: React.FC = ({ aria-label={ariaLabel} /> ); -}; - -FieldComponent.displayName = 'Field'; +} diff --git a/packages/kbn-securitysolution-autocomplete/src/field/types.ts b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/types.ts similarity index 85% rename from packages/kbn-securitysolution-autocomplete/src/field/types.ts rename to packages/kbn-securitysolution-autocomplete/src/es_field_selector/types.ts index 26e0eb9697705..b0f1ab56e8079 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field/types.ts +++ b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/types.ts @@ -11,15 +11,6 @@ import { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; import { FieldConflictsInfo } from '@kbn/securitysolution-list-utils'; import { GetGenericComboBoxPropsReturn } from '../get_generic_combo_box_props'; -export interface FieldProps extends FieldBaseProps { - isClearable: boolean; - isDisabled: boolean; - isLoading: boolean; - placeholder: string; - acceptsCustomOptions?: boolean; - showMappingConflicts?: boolean; - 'aria-label'?: string; -} export interface FieldBaseProps { indexPattern: DataViewBase | undefined; fieldTypeFilter?: string[]; diff --git a/packages/kbn-securitysolution-autocomplete/src/field/use_field.tsx b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/use_es_field.tsx similarity index 99% rename from packages/kbn-securitysolution-autocomplete/src/field/use_field.tsx rename to packages/kbn-securitysolution-autocomplete/src/es_field_selector/use_es_field.tsx index 7a0b7eb5b00af..615571d989607 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field/use_field.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/es_field_selector/use_es_field.tsx @@ -115,7 +115,7 @@ const getComboBoxProps = (fields: ComboBoxFields): GetFieldComboBoxPropsReturn = }; }; -export const useField = ({ +export const useEsField = ({ indexPattern, fieldTypeFilter, isRequired, diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx index 6a831376b3cbf..5b627451db191 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx @@ -48,9 +48,9 @@ interface AutocompleteFieldMatchProps { selectedField: DataViewFieldBase | undefined; selectedValue: string | undefined; indexPattern: DataViewBase | undefined; - isLoading: boolean; - isDisabled: boolean; - isClearable: boolean; + isLoading?: boolean; + isDisabled?: boolean; + isClearable?: boolean; isRequired?: boolean; fieldInputWidth?: number; rowLabel?: string; @@ -68,7 +68,7 @@ export const AutocompleteFieldMatchComponent: React.FC = ({ (isFirst: boolean): JSX.Element => { const filteredIndexPatterns = getFilteredIndexPatterns(indexPattern, entry); const comboBox = ( - = ({ const renderFieldInput = useMemo(() => { const comboBox = ( - = ({ const renderThreatFieldInput = useMemo(() => { const comboBox = ( - > | undefined { const [{ value, path, form }] = args; - const formData = form.getFormData(); - const parentFieldData: RequiredFieldInput[] = formData[parentFieldPath]; + const allRequiredFields = getAllRequiredFieldsValues(form, parentFieldPath); const isFieldNameUsedMoreThanOnce = - parentFieldData.filter((field) => field.name === value.name).length > 1; + allRequiredFields.filter((field) => field.name === value.name).length > 1; if (isFieldNameUsedMoreThanOnce) { return { @@ -51,3 +51,20 @@ export function makeValidateRequiredField(parentFieldPath: string) { } }; } + +function getAllRequiredFieldsValues( + form: { getFields: FormHook['getFields'] }, + parentFieldPath: string +) { + /* + Getting values for required fields via flattened fields instead of using `getFormData`. + This is because `getFormData` applies a serializer function to field values, which might update values. + Using flattened fields allows us to get the original values before the serializer function is applied. + */ + const flattenedFieldNames = getFlattenedArrayFieldNames(form, parentFieldPath); + const fields = form.getFields(); + + return flattenedFieldNames.map( + (fieldName) => fields[fieldName]?.value ?? {} + ) as RequiredFieldInput[]; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/required_fields.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/required_fields.tsx index f53c41ce98d00..f2f4c08a35813 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/required_fields.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/required_fields.tsx @@ -16,6 +16,7 @@ import { RequiredFieldsHelpInfo } from './required_fields_help_info'; import { RequiredFieldRow } from './required_fields_row'; import * as defineRuleI18n from '../../../rule_creation_ui/components/step_define_rule/translations'; import * as i18n from './translations'; +import { getFlattenedArrayFieldNames } from './utils'; interface RequiredFieldsComponentProps { path: string; @@ -65,7 +66,7 @@ const RequiredFieldsList = ({ form, }: RequiredFieldsListProps) => { /* - This component should only re-render when either the "index" form field (index patterns) or the required fields change. + This component should only re-render when either the "index" form field (index patterns) or the required fields change. By default, the `useFormData` hook triggers a re-render whenever any form field changes. It also allows optimization by passing a "watch" array of field names. The component then only re-renders when these specified fields change. @@ -77,10 +78,7 @@ const RequiredFieldsList = ({ To work around this, we manually construct a list of "flattened" field names to watch, based on the current state of the form. This is a temporary solution and ideally, `useFormData` should be updated to handle this scenario. */ - - const internalField = form.getFields()[`${path}__array__`] ?? {}; - const internalFieldValue = (internalField?.value ?? []) as ArrayItem[]; - const flattenedFieldNames = internalFieldValue.map((item) => item.path); + const flattenedFieldNames = getFlattenedArrayFieldNames(form, path); /* Not using "watch" for the initial render, to let row components render and initialize form fields. diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/required_fields_row.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/required_fields_row.tsx index 755f1de413760..39b08ac17e49f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/required_fields_row.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/required_fields_row.tsx @@ -44,14 +44,6 @@ export const RequiredFieldRow = ({ const rowFieldConfig: FieldConfig = useMemo( () => ({ - deserializer: (value) => { - const rowValueWithoutEcs: RequiredFieldInput = { - name: value.name, - type: value.type, - }; - - return rowValueWithoutEcs; - }, validations: [{ validator: makeValidateRequiredField(parentFieldPath) }], defaultValue: { name: '', type: '' }, }), diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/utils.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/utils.ts index 55beca264e120..38820e992fa69 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/utils.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/required_fields/utils.ts @@ -5,6 +5,8 @@ * 2.0. */ +import type { FormHook, ArrayItem } from '../../../../shared_imports'; + interface PickTypeForNameParameters { name: string; type: string; @@ -26,3 +28,26 @@ export function pickTypeForName({ name, type, typesByFieldName = {} }: PickTypeF */ return typesAvailableForName[0] ?? type; } + +/** + * Returns a list of flattened field names for a given array field of a form. + * Flattened field name is a string that represents the path to an item in an array field. + * For example, a field "myArrayField" can be represented as "myArrayField[0]", "myArrayField[1]", etc. + * + * Flattened field names are useful: + * - when you need to subscribe to changes in an array field using `useFormData` "watch" option + * - when you need to retrieve form data before serializer function is applied + * + * @param {Object} form - Form object. + * @param {string} arrayFieldName - Path to the array field. + * @returns {string[]} - Flattened array field names. + */ +export function getFlattenedArrayFieldNames( + form: { getFields: FormHook['getFields'] }, + arrayFieldName: string +): string[] { + const internalField = form.getFields()[`${arrayFieldName}__array__`] ?? {}; + const internalFieldValue = (internalField?.value ?? []) as ArrayItem[]; + + return internalFieldValue.map((item) => item.path); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/autocomplete_field/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/es_field_selector_field/index.tsx similarity index 70% rename from x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/autocomplete_field/index.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/es_field_selector_field/index.tsx index 37c19f5724ec8..03d0a3021dc33 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/autocomplete_field/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/es_field_selector_field/index.tsx @@ -7,13 +7,13 @@ import React, { useCallback, useMemo } from 'react'; import { EuiFormRow } from '@elastic/eui'; -import { FieldComponent } from '@kbn/securitysolution-autocomplete'; +import { EsFieldSelector } from '@kbn/securitysolution-autocomplete'; import type { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; import type { FieldHook } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; -interface AutocompleteFieldProps { +interface EsFieldSelectorFieldProps { dataTestSubj: string; - field: FieldHook; + field: FieldHook; idAria: string; indices: DataViewBase; isDisabled: boolean; @@ -21,7 +21,7 @@ interface AutocompleteFieldProps { placeholder?: string; } -export const AutocompleteField = ({ +export const EsFieldSelectorField = ({ dataTestSubj, field, idAria, @@ -29,35 +29,37 @@ export const AutocompleteField = ({ isDisabled, fieldType, placeholder, -}: AutocompleteFieldProps) => { +}: EsFieldSelectorFieldProps) => { + const fieldTypeFilter = useMemo(() => [fieldType], [fieldType]); + const handleFieldChange = useCallback( ([newField]: DataViewFieldBase[]): void => { - // TODO: Update onChange type in FieldComponent as newField can be undefined field.setValue(newField?.name ?? ''); }, [field] ); - const selectedField = useMemo(() => { - const existingField = (field.value as string) ?? ''; - const [newSelectedField] = indices.fields.filter( - ({ name }) => existingField != null && existingField === name - ); - return newSelectedField; - }, [field.value, indices]); + const selectedField = useMemo( + () => + indices.fields.find(({ name }) => field.value === name) ?? { + name: field.value, + type: fieldType, + }, + [field.value, indices, fieldType] + ); - const fieldTypeFilter = useMemo(() => [fieldType], [fieldType]); + const describedByIds = useMemo(() => (idAria ? [idAria] : undefined), [idAria]); return ( - = ({ const { alerting } = useKibana().services; const maxAlertsPerRun = alerting.getMaxAlertsPerRun(); - const [isInvalid, error] = useMemo(() => { - if (typeof value === 'number' && !isNaN(value) && value <= 0) { - return [true, i18n.GREATER_THAN_ERROR]; - } - return [false]; - }, [value]); + const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field); const hasWarning = useMemo( () => typeof value === 'number' && !isNaN(value) && value > maxAlertsPerRun, @@ -67,6 +66,8 @@ export const MaxSignals: React.FC = ({ return textToRender; }, [hasWarning, maxAlertsPerRun]); + const describedByIds = useMemo(() => (idAria ? [idAria] : undefined), [idAria]); + return ( = ({ width: ${MAX_SIGNALS_FIELD_WIDTH}px; } `} - describedByIds={idAria ? [idAria] : undefined} + describedByIds={describedByIds} fullWidth helpText={helpText} label={field.label} labelAppend={field.labelAppend} isInvalid={isInvalid} - error={error} + error={errorMessage} > = ({ data-test-subj={dataTestSubj} disabled={isDisabled} append={hasWarning ? : undefined} + min={MIN_VALUE} /> ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/max_signals/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/max_signals/translations.ts index b69c0557a051f..b5b135d456f34 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/max_signals/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/max_signals/translations.ts @@ -7,13 +7,6 @@ import { i18n } from '@kbn/i18n'; -export const GREATER_THAN_ERROR = i18n.translate( - 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldGreaterThanError', - { - defaultMessage: 'Max alerts must be greater than 0.', - } -); - export const LESS_THAN_WARNING = (maxNumber: number) => i18n.translate( 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/default_risk_score.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/default_risk_score.tsx new file mode 100644 index 0000000000000..94899f35e2728 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/default_risk_score.tsx @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback } from 'react'; +import { EuiFormRow, EuiText, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiRange } from '@elastic/eui'; +import type { EuiRangeProps } from '@elastic/eui'; +import { MAX_RISK_SCORE, MIN_RISK_SCORE } from '../../validators/default_risk_score_validator'; +import * as i18n from './translations'; + +interface DefaultRiskScoreProps { + value: number; + onChange: (newValue: number) => void; + errorMessage?: string; + idAria?: string; + dataTestSubj?: string; +} + +export function DefaultRiskScore({ + value, + onChange, + errorMessage, + idAria, + dataTestSubj = 'defaultRiskScore', +}: DefaultRiskScoreProps) { + const handleChange = useCallback>( + (event) => { + const eventValue = (event.target as HTMLInputElement).value; + const intOrNanValue = Number.parseInt(eventValue.trim(), 10); + const intValue = Number.isNaN(intOrNanValue) ? MIN_RISK_SCORE : intOrNanValue; + + onChange(intValue); + }, + [onChange] + ); + + return ( + + } + error={errorMessage} + isInvalid={!!errorMessage} + fullWidth + data-test-subj={`${dataTestSubj}-defaultRisk`} + describedByIds={idAria ? [idAria] : undefined} + > + + + + ); +} + +function DefaultRiskScoreLabel() { + return ( +
+ + {i18n.DEFAULT_RISK_SCORE} + + + {i18n.RISK_SCORE_DESCRIPTION} +
+ ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/index.tsx index 1cd775c2e80e5..d5360bbf04001 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/index.tsx @@ -5,45 +5,16 @@ * 2.0. */ -import React, { useCallback, useMemo } from 'react'; -import styled from 'styled-components'; -import { noop } from 'lodash/fp'; -import { - EuiFormRow, - EuiCheckbox, - EuiText, - EuiFlexGroup, - EuiFlexItem, - EuiFormLabel, - EuiIcon, - EuiSpacer, - EuiRange, -} from '@elastic/eui'; -import type { EuiRangeProps } from '@elastic/eui'; - +import React, { useCallback } from 'react'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import type { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; -import type { FieldHook } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; -import { FieldComponent } from '@kbn/securitysolution-autocomplete'; -import type { RiskScoreMapping } from '@kbn/securitysolution-io-ts-alerting-types'; - +import { + getFieldValidityAndErrorMessage, + type FieldHook, +} from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; import type { AboutStepRiskScore } from '../../../../detections/pages/detection_engine/rules/types'; -import * as i18n from './translations'; - -const NestedContent = styled.div` - margin-left: 24px; -`; - -const EuiFlexItemComboBoxColumn = styled(EuiFlexItem)` - max-width: 376px; -`; - -const EuiFlexItemIconColumn = styled(EuiFlexItem)` - width: 20px; -`; - -const EuiFlexItemRiskScoreColumn = styled(EuiFlexItem)` - width: 160px; -`; +import { DefaultRiskScore } from './default_risk_score'; +import { RiskScoreOverride } from './risk_score_override'; interface RiskScoreFieldProps { dataTestSubj: string; @@ -51,7 +22,6 @@ interface RiskScoreFieldProps { idAria: string; indices: DataViewBase; isDisabled: boolean; - placeholder?: string; } export const RiskScoreField = ({ @@ -60,19 +30,14 @@ export const RiskScoreField = ({ idAria, indices, isDisabled, - placeholder, }: RiskScoreFieldProps) => { const { value, isMappingChecked, mapping } = field.value; const { setValue } = field; - const fieldTypeFilter = useMemo(() => ['number'], []); - const selectedField = useMemo(() => getFieldTypeByMapping(mapping, indices), [mapping, indices]); - - const handleDefaultRiskScoreChange = useCallback>( - (e) => { - const range = (e.target as HTMLInputElement).value; + const handleDefaultRiskScoreChange = useCallback( + (newDefaultRiskScoreValue: number) => { setValue({ - value: Number(range.trim()), + value: newDefaultRiskScoreValue, isMappingChecked, mapping, }); @@ -106,146 +71,29 @@ export const RiskScoreField = ({ }); }, [setValue, value, isMappingChecked, mapping]); - const riskScoreLabel = useMemo(() => { - return ( -
- - {i18n.DEFAULT_RISK_SCORE} - - - {i18n.RISK_SCORE_DESCRIPTION} -
- ); - }, []); - - const riskScoreMappingLabel = useMemo(() => { - return ( -
- - - - - {i18n.RISK_SCORE_MAPPING} - - - - {i18n.RISK_SCORE_MAPPING_DESCRIPTION} - -
- ); - }, [isMappingChecked, handleRiskScoreMappingChecked, isDisabled]); + const errorMessage = getFieldValidityAndErrorMessage(field).errorMessage ?? undefined; return ( + - - - - - - {i18n.RISK_SCORE_MAPPING_DETAILS} : '' - } - error={'errorMessage'} - isInvalid={false} - fullWidth - data-test-subj={`${dataTestSubj}-riskOverride`} - describedByIds={idAria ? [idAria] : undefined} - > - - - {isMappingChecked && ( - - - - - {i18n.SOURCE_FIELD} - - - - {i18n.DEFAULT_RISK_SCORE} - - - - - - - - - - - - - - {i18n.RISK_SCORE_FIELD} - - - - - )} - - + ); }; - -/** - * Looks for field metadata (DataViewFieldBase) in existing index pattern. - * If specified field doesn't exist, returns a stub DataViewFieldBase created based on the mapping -- - * because the field might not have been indexed yet, but we still need to display the mapping. - * - * @param mapping Mapping of a specified field name to risk score. - * @param pattern Existing index pattern. - */ -const getFieldTypeByMapping = ( - mapping: RiskScoreMapping, - pattern: DataViewBase -): DataViewFieldBase => { - const field = mapping?.[0]?.field ?? ''; - const [knownFieldType] = pattern.fields.filter(({ name }) => field != null && field === name); - return knownFieldType ?? { name: field, type: 'number' }; -}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/risk_score_override.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/risk_score_override.tsx new file mode 100644 index 0000000000000..d6067062685f7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/risk_score_mapping/risk_score_override.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, { useMemo } from 'react'; +import { noop } from 'lodash/fp'; +import styled from 'styled-components'; +import { + EuiFormRow, + EuiCheckbox, + EuiText, + EuiFlexGroup, + EuiFlexItem, + EuiFormLabel, + EuiIcon, + EuiSpacer, +} from '@elastic/eui'; +import type { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; +import { EsFieldSelector } from '@kbn/securitysolution-autocomplete'; +import * as i18n from './translations'; +import type { RiskScoreMapping } from '../../../../../common/api/detection_engine'; + +const NestedContent = styled.div` + margin-left: 24px; +`; + +const EuiFlexItemComboBoxColumn = styled(EuiFlexItem)` + max-width: 376px; +`; + +const EuiFlexItemIconColumn = styled(EuiFlexItem)` + width: 20px; +`; + +const EuiFlexItemRiskScoreColumn = styled(EuiFlexItem)` + width: 160px; +`; + +const fieldTypeFilter = ['number']; + +interface RiskScoreOverrideProps { + isMappingChecked: boolean; + onToggleMappingChecked: () => void; + onMappingChange: ([newField]: DataViewFieldBase[]) => void; + mapping: RiskScoreMapping; + indices: DataViewBase; + dataTestSubj?: string; + idAria?: string; + isDisabled: boolean; +} + +export function RiskScoreOverride({ + isMappingChecked, + onToggleMappingChecked, + onMappingChange, + mapping, + indices, + dataTestSubj = 'riskScoreOverride', + idAria, + isDisabled, +}: RiskScoreOverrideProps) { + const riskScoreMappingLabel = useMemo(() => { + return ( +
+ + + + + {i18n.RISK_SCORE_MAPPING} + + + + {i18n.RISK_SCORE_MAPPING_DESCRIPTION} + +
+ ); + }, [isDisabled, isMappingChecked, onToggleMappingChecked]); + + const describedByIds = useMemo(() => (idAria ? [idAria] : undefined), [idAria]); + const selectedField = useMemo(() => getFieldTypeByMapping(mapping, indices), [mapping, indices]); + + return ( + {i18n.RISK_SCORE_MAPPING_DETAILS} : '' + } + fullWidth + data-test-subj={`${dataTestSubj}-riskOverride`} + describedByIds={describedByIds} + > + + + {isMappingChecked && ( + + + + + {i18n.SOURCE_FIELD} + + + + {i18n.DEFAULT_RISK_SCORE} + + + + + + + + + + + + + + {i18n.RISK_SCORE_FIELD} + + + + + )} + + + ); +} + +/** + * Looks for field metadata (DataViewFieldBase) in existing index pattern. + * If specified field doesn't exist, returns a stub DataViewFieldBase created based on the mapping -- + * because the field might not have been indexed yet, but we still need to display the mapping. + * + * @param mapping Mapping of a specified field name to risk score. + * @param pattern Existing index pattern. + */ +const getFieldTypeByMapping = ( + mapping: RiskScoreMapping, + pattern: DataViewBase +): DataViewFieldBase => { + const field = mapping?.[0]?.field ?? ''; + const [knownFieldType] = pattern.fields.filter(({ name }) => field != null && field === name); + return knownFieldType ?? { name: field, type: 'number' }; +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx new file mode 100644 index 0000000000000..477b4bcd0f519 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/default_severity.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiFormRow, + EuiText, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, + EuiSuperSelect, +} from '@elastic/eui'; +import React from 'react'; +import type { Severity } from '../../../../../common/api/detection_engine/model/rule_schema/common_attributes.gen'; +import { severityOptions } from '../step_about_rule/data'; +import * as i18n from './translations'; + +const describedByIds = ['detectionEngineStepAboutRuleSeverity']; + +interface DefaultSeverityProps { + value: Severity; + onChange: (newValue: Severity) => void; +} + +export function DefaultSeverity({ value, onChange }: DefaultSeverityProps) { + return ( + + } + fullWidth + data-test-subj="detectionEngineStepAboutRuleSeverity" + describedByIds={describedByIds} + > + + + + ); +} + +function DefaultSeverityLabel() { + return ( +
+ + {i18n.SEVERITY} + + + {i18n.SEVERITY_DESCRIPTION} +
+ ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/index.tsx index 425564e1ed5f2..28d0a2c622414 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/index.tsx @@ -5,53 +5,14 @@ * 2.0. */ -import { - EuiFormRow, - EuiCheckbox, - EuiText, - EuiFlexGroup, - EuiFlexItem, - EuiFormLabel, - EuiIcon, - EuiSpacer, - EuiSuperSelect, -} from '@elastic/eui'; -import { noop } from 'lodash/fp'; -import React, { useCallback, useMemo } from 'react'; -import styled from 'styled-components'; - +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import React, { useCallback } from 'react'; import type { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; import type { FieldHook } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; -import { - FieldComponent, - AutocompleteFieldMatchComponent, -} from '@kbn/securitysolution-autocomplete'; -import type { - Severity, - SeverityMapping, - SeverityMappingItem, -} from '@kbn/securitysolution-io-ts-alerting-types'; - -import type { SeverityOptionItem } from '../step_about_rule/data'; +import type { Severity, SeverityMapping } from '@kbn/securitysolution-io-ts-alerting-types'; import type { AboutStepSeverity } from '../../../../detections/pages/detection_engine/rules/types'; -import { useKibana } from '../../../../common/lib/kibana'; -import * as i18n from './translations'; - -const NestedContent = styled.div` - margin-left: 24px; -`; - -const EuiFlexItemComboBoxColumn = styled(EuiFlexItem)` - max-width: 376px; -`; - -const EuiFlexItemIconColumn = styled(EuiFlexItem)` - width: 20px; -`; - -const EuiFlexItemSeverityColumn = styled(EuiFlexItem)` - width: 80px; -`; +import { DefaultSeverity } from './default_severity'; +import { SeverityOverride } from './severity_override'; interface SeverityFieldProps { dataTestSubj: string; @@ -59,7 +20,6 @@ interface SeverityFieldProps { idAria: string; indices: DataViewBase; isDisabled: boolean; - options: SeverityOptionItem[]; setRiskScore: (severity: Severity) => void; } @@ -69,10 +29,8 @@ export const SeverityField = ({ idAria, indices, isDisabled, - options, setRiskScore, }: SeverityFieldProps) => { - const { services } = useKibana(); const { value, isMappingChecked, mapping } = field.value; const { setValue } = field; @@ -126,6 +84,7 @@ export const SeverityField = ({ severity, }, ]; + handleFieldValueChange(newMappingItems, index); }, [mapping, handleFieldValueChange] @@ -139,178 +98,22 @@ export const SeverityField = ({ }); }, [isMappingChecked, mapping, value, setValue]); - const severityLabel = useMemo(() => { - return ( -
- - {i18n.SEVERITY} - - - {i18n.SEVERITY_DESCRIPTION} -
- ); - }, []); - - const severityMappingLabel = useMemo(() => { - return ( -
- - - - - {i18n.SEVERITY_MAPPING} - - - - {i18n.SEVERITY_MAPPING_DESCRIPTION} - -
- ); - }, [handleSeverityMappingChecked, isDisabled, isMappingChecked]); - return ( + - - - - - - - {i18n.SEVERITY_MAPPING_DETAILS} : '' - } - error={'errorMessage'} - isInvalid={false} - fullWidth - data-test-subj={`${dataTestSubj}-severityOverride`} - describedByIds={idAria ? [idAria] : undefined} - > - - - {isMappingChecked && ( - - - - - {i18n.SOURCE_FIELD} - - - {i18n.SOURCE_VALUE} - - - - {i18n.DEFAULT_SEVERITY} - - - - - {mapping.map((severityMappingItem: SeverityMappingItem, index) => ( - - - - - - - - - - - - - - { - options.find((o) => o.value === severityMappingItem.severity) - ?.inputDisplay - } - - - - ))} - - )} - - + ); }; - -/** - * Looks for field metadata (DataViewFieldBase) in existing index pattern. - * If specified field doesn't exist, returns a stub DataViewFieldBase created based on the mapping -- - * because the field might not have been indexed yet, but we still need to display the mapping. - * - * @param mapping Mapping of a specified field name + value to a certain severity value. - * @param pattern Existing index pattern. - */ -const getFieldTypeByMapping = ( - mapping: SeverityMappingItem, - pattern: DataViewBase -): DataViewFieldBase => { - const { field } = mapping; - const [knownFieldType] = pattern.fields.filter(({ name }) => field === name); - return knownFieldType ?? { name: field, type: 'string' }; -}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/severity_override.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/severity_override.tsx new file mode 100644 index 0000000000000..046f360c3af4d --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/severity_override.tsx @@ -0,0 +1,234 @@ +/* + * Copyright 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, + EuiCheckbox, + EuiText, + EuiFlexGroup, + EuiFlexItem, + EuiFormLabel, + EuiIcon, + EuiSpacer, +} from '@elastic/eui'; +import React, { useCallback, useMemo } from 'react'; +import type { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; +import { + EsFieldSelector, + AutocompleteFieldMatchComponent, +} from '@kbn/securitysolution-autocomplete'; +import type { Severity, SeverityMappingItem } from '@kbn/securitysolution-io-ts-alerting-types'; +import { severityOptions } from '../step_about_rule/data'; +import { useKibana } from '../../../../common/lib/kibana'; +import * as styles from './styles'; +import * as i18n from './translations'; + +interface SeverityOverrideProps { + isDisabled: boolean; + onSeverityMappingChecked: () => void; + onFieldChange: (index: number, severity: Severity, [newField]: DataViewFieldBase[]) => void; + onFieldMatchValueChange: (index: number, severity: Severity, newMatchValue: string) => void; + isMappingChecked: boolean; + dataTestSubj?: string; + idAria?: string; + mapping: SeverityMappingItem[]; + indices: DataViewBase; +} + +export function SeverityOverride({ + isDisabled, + onSeverityMappingChecked, + onFieldChange, + onFieldMatchValueChange, + isMappingChecked, + dataTestSubj = 'severity', + idAria, + mapping, + indices, +}: SeverityOverrideProps) { + const severityMappingLabel = useMemo(() => { + return ( +
+ + + + + {i18n.SEVERITY_MAPPING} + + + + {i18n.SEVERITY_MAPPING_DESCRIPTION} + +
+ ); + }, [onSeverityMappingChecked, isDisabled, isMappingChecked]); + + const describedByIds = useMemo(() => (idAria ? [idAria] : undefined), [idAria]); + + return ( + {i18n.SEVERITY_MAPPING_DETAILS} : '' + } + fullWidth + data-test-subj={`${dataTestSubj}-severityOverride`} + describedByIds={describedByIds} + > + + + {isMappingChecked && ( + + + + + {i18n.SOURCE_FIELD} + + + {i18n.SOURCE_VALUE} + + + + {i18n.DEFAULT_SEVERITY} + + + + + {mapping.map((severityMappingItem, index) => ( + + ))} + + )} + + + ); +} + +interface SeverityMappingRowProps { + severityMappingItem: SeverityMappingItem; + index: number; + indices: DataViewBase; + isDisabled: boolean; + onFieldChange: (index: number, severity: Severity, [newField]: DataViewFieldBase[]) => void; + onFieldMatchValueChange: (index: number, severity: Severity, newMatchValue: string) => void; +} + +function SeverityMappingRow({ + severityMappingItem, + index, + indices, + isDisabled, + onFieldChange, + onFieldMatchValueChange, +}: SeverityMappingRowProps) { + const { services } = useKibana(); + + const handleFieldChange = useCallback( + (newField: DataViewFieldBase[]) => { + onFieldChange(index, severityMappingItem.severity, newField); + }, + [index, severityMappingItem.severity, onFieldChange] + ); + + const handleFieldMatchValueChange = useCallback( + (newMatchValue: string) => { + onFieldMatchValueChange(index, severityMappingItem.severity, newMatchValue); + }, + [index, severityMappingItem.severity, onFieldMatchValueChange] + ); + + return ( + + + + + + + + + + + + + + {severityOptions.find((o) => o.value === severityMappingItem.severity)?.inputDisplay} + + + + ); +} + +const NestedContent: React.FC = ({ children }) => ( +
{children}
+); + +const EuiFlexItemComboBoxColumn: React.FC = ({ children }) => ( + {children} +); + +const EuiFlexItemIconColumn: React.FC = ({ children }) => ( + + {children} + +); + +const EuiFlexItemSeverityColumn: React.FC = ({ children }) => ( + + {children} + +); + +/** + * Looks for field metadata (DataViewFieldBase) in existing index pattern. + * If specified field doesn't exist, returns a stub DataViewFieldBase created based on the mapping -- + * because the field might not have been indexed yet, but we still need to display the mapping. + * + * @param mapping Mapping of a specified field name + value to a certain severity value. + * @param pattern Existing index pattern. + */ +const getFieldTypeByMapping = ( + mapping: SeverityMappingItem, + pattern: DataViewBase +): DataViewFieldBase => { + const { field } = mapping; + const [knownFieldType] = pattern.fields.filter(({ name }) => field === name); + return knownFieldType ?? { name: field, type: 'string' }; +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/styles.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/styles.ts new file mode 100644 index 0000000000000..480a442b250d9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/severity_mapping/styles.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 { css } from '@emotion/css'; + +export const nestedContent = css` + margin-left: 24px; +`; + +export const comboBoxColumn = css` + max-width: 376px; +`; + +export const iconColumn = css` + width: 20px; +`; + +export const severityColumn = css` + width: 80px; +`; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.tsx index 7666a9ba8aee3..ac5c91aa8a25a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.tsx @@ -24,7 +24,7 @@ import { AddMitreAttackThreat } from '../mitre'; import type { FieldHook, FormHook } from '../../../../shared_imports'; import { Field, Form, getUseField, UseField } from '../../../../shared_imports'; -import { defaultRiskScoreBySeverity, severityOptions } from './data'; +import { defaultRiskScoreBySeverity } from './data'; import { isUrlInvalid } from '../../../../common/utils/validators'; import { schema as defaultSchema } from './schema'; import * as I18n from './translations'; @@ -32,7 +32,7 @@ import { StepContentWrapper } from '../../../rule_creation/components/step_conte import { MarkdownEditorForm } from '../../../../common/components/markdown_editor/eui_form'; import { SeverityField } from '../severity_mapping'; import { RiskScoreField } from '../risk_score_mapping'; -import { AutocompleteField } from '../autocomplete_field'; +import { EsFieldSelectorField } from '../es_field_selector_field'; import { useFetchIndex } from '../../../../common/containers/source'; import { DEFAULT_INDICATOR_SOURCE_PATH, @@ -176,7 +176,6 @@ const StepAboutRuleComponent: FC = ({ dataTestSubj: 'detectionEngineStepAboutRuleSeverityField', idAria: 'detectionEngineStepAboutRuleSeverityField', isDisabled: isLoading || indexPatternLoading, - options: severityOptions, indices: indexPattern, setRiskScore, }} @@ -376,14 +375,13 @@ const StepAboutRuleComponent: FC = ({ ) : ( )} @@ -391,14 +389,13 @@ const StepAboutRuleComponent: FC = ({ {!!timestampOverride && timestampOverride !== '@timestamp' && ( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/schema.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/schema.tsx index 83d79debb757d..66c599d0dc721 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/schema.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/schema.tsx @@ -7,12 +7,22 @@ import { i18n } from '@kbn/i18n'; -import type { FormSchema, ValidationFunc, ERROR_CODE } from '../../../../shared_imports'; +import type { + FormSchema, + ValidationFunc, + ERROR_CODE, + ValidationError, +} from '../../../../shared_imports'; import { FIELD_TYPES, fieldValidators, VALIDATION_TYPES } from '../../../../shared_imports'; -import type { AboutStepRule } from '../../../../detections/pages/detection_engine/rules/types'; +import type { + AboutStepRiskScore, + AboutStepRule, +} from '../../../../detections/pages/detection_engine/rules/types'; import { OptionalFieldLabel } from '../optional_field_label'; import { isUrlInvalid } from '../../../../common/utils/validators'; import * as I18n from './translations'; +import { defaultRiskScoreValidator } from '../../validators/default_risk_score_validator'; +import { maxSignalsValidatorFactory } from '../../validators/max_signals_validator_factory'; const { emptyField } = fieldValidators; @@ -109,6 +119,11 @@ export const schema: FormSchema = { } ), labelAppend: OptionalFieldLabel, + validations: [ + { + validator: maxSignalsValidatorFactory(), + }, + ], }, isAssociatedToEndpointList: { type: FIELD_TYPES.CHECKBOX, @@ -129,6 +144,18 @@ export const schema: FormSchema = { value: {}, mapping: {}, isMappingChecked: {}, + validations: [ + { + validator: ( + ...args: Parameters> + ): ValidationError | undefined => { + const [{ value: fieldValue, path }] = args; + const defaultRiskScore = fieldValue.value; + + return defaultRiskScoreValidator(defaultRiskScore, path); + }, + }, + ], }, references: { label: i18n.translate( diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.test.tsx index 9bcf35fdb13ca..f1dcfc74e7923 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.test.tsx @@ -365,7 +365,7 @@ describe.skip('StepDefineRule', () => { ); }); - it('submits saved early required fields without the "ecs" property', async () => { + it('submits saved earlier required fields', async () => { const initialState = { index: ['test-index'], queryBar: { @@ -390,7 +390,7 @@ describe.skip('StepDefineRule', () => { expect(handleSubmit).toHaveBeenCalledWith( expect.objectContaining({ - requiredFields: [{ name: 'host.name', type: 'string' }], + requiredFields: initialState.requiredFields, }), true ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.ts index 46dde209804f2..7d80ce7423257 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.ts @@ -19,6 +19,7 @@ import type { List, } from '@kbn/securitysolution-io-ts-list-types'; import type { + RiskScoreMappingItem, Threats, ThreatSubtechnique, ThreatTechnique, @@ -57,6 +58,8 @@ import type { RuleCreateProps, AlertSuppression, RequiredFieldInput, + SeverityMapping, + RelatedIntegrationArray, } from '../../../../../common/api/detection_engine/model/rule_schema'; import { stepActionsDefaultValue } from '../../../rule_creation/components/step_rule_actions'; import { DEFAULT_SUPPRESSION_MISSING_FIELDS_STRATEGY } from '../../../../../common/detection_engine/constants'; @@ -407,8 +410,9 @@ export const getStepDataDataSource = ( /** * Strips away form rows that were not filled out by the user */ -const removeEmptyRequiredFields = (requiredFields: RequiredFieldInput[]): RequiredFieldInput[] => - requiredFields.filter((field) => field.name !== '' && field.type !== ''); +export const removeEmptyRequiredFields = ( + requiredFields: RequiredFieldInput[] +): RequiredFieldInput[] => requiredFields.filter((field) => field.name !== '' && field.type !== ''); export const formatDefineStepData = (defineStepData: DefineStepRule): DefineStepRuleJson => { const stepData = getStepDataDataSource(defineStepData); @@ -418,7 +422,9 @@ export const formatDefineStepData = (defineStepData: DefineStepRule): DefineStep const baseFields = { type: ruleType, - related_integrations: defineStepData.relatedIntegrations?.filter((ri) => !isEmpty(ri.package)), + related_integrations: defineStepData.relatedIntegrations + ? filterOutEmptyRelatedIntegrations(defineStepData.relatedIntegrations) + : undefined, ...(timeline.id != null && timeline.title != null && { timeline_id: timeline.id, @@ -624,12 +630,12 @@ export const formatAboutStepData = ( : { field_names: investigationFields }, risk_score: riskScore.value, risk_score_mapping: riskScore.isMappingChecked - ? riskScore.mapping.filter((m) => m.field != null && m.field !== '') + ? filterOutEmptyRiskScoreMappingItems(riskScore.mapping) : [], rule_name_override: ruleNameOverride !== '' ? ruleNameOverride : undefined, severity: severity.value, severity_mapping: severity.isMappingChecked - ? severity.mapping.filter((m) => m.field != null && m.field !== '' && m.value != null) + ? filterOutEmptySeverityMappingItems(severity.mapping) : [], threat: filterEmptyThreats(threat).map((singleThreat) => ({ ...singleThreat, @@ -645,6 +651,15 @@ export const formatAboutStepData = ( return resp; }; +export const filterOutEmptyRiskScoreMappingItems = (riskScoreMapping: RiskScoreMappingItem[]) => + riskScoreMapping.filter((m) => m.field != null && m.field !== ''); + +export const filterOutEmptySeverityMappingItems = (severityMapping: SeverityMapping) => + severityMapping.filter((m) => m.field != null && m.field !== '' && m.value != null); + +export const filterOutEmptyRelatedIntegrations = (relatedIntegrations: RelatedIntegrationArray) => + relatedIntegrations.filter((ri) => !isEmpty(ri.package)); + export const isRuleAction = ( action: AlertingRuleAction | AlertingRuleSystemAction, actionTypeRegistry: ActionTypeRegistryContract diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/validators/default_risk_score_validator.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/validators/default_risk_score_validator.ts new file mode 100644 index 0000000000000..6fd7255d48294 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/validators/default_risk_score_validator.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const MIN_RISK_SCORE = 0; +export const MAX_RISK_SCORE = 100; + +export function defaultRiskScoreValidator(defaultRiskScore: unknown, path: string) { + return isDefaultRiskScoreWithinRange(defaultRiskScore) + ? undefined + : { + path, + message: i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleCreation.validation.defaultRiskScoreOutOfRangeValidationError', + { + values: { min: MIN_RISK_SCORE, max: MAX_RISK_SCORE }, + defaultMessage: 'Risk score must be between {min} and {max}.', + } + ), + }; +} + +function isDefaultRiskScoreWithinRange(value: unknown) { + return typeof value === 'number' && value >= MIN_RISK_SCORE && value <= MAX_RISK_SCORE; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/validators/max_signals_validator_factory.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/validators/max_signals_validator_factory.ts new file mode 100644 index 0000000000000..b50e0dc4662a5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/validators/max_signals_validator_factory.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 { i18n } from '@kbn/i18n'; +import type { ERROR_CODE } from '../../../shared_imports'; +import { fieldValidators, type FormData, type ValidationFunc } from '../../../shared_imports'; + +export const MIN_VALUE = 1; + +export function maxSignalsValidatorFactory(): ValidationFunc { + return fieldValidators.numberGreaterThanField({ + than: MIN_VALUE, + allowEquality: true, + message: i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleCreation.validation.maxSignals.greaterThanError', + { + values: { min: MIN_VALUE }, + defaultMessage: 'Max alerts must be greater than {min}.', + } + ), + }); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx index fefd35fcfaf65..3f10ce014d82e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/common_rule_field_edit.tsx @@ -7,16 +7,247 @@ import React from 'react'; import { RuleFieldEditFormWrapper } from './fields/rule_field_edit_form_wrapper'; -import { NameEdit, nameSchema } from './fields/name'; import type { UpgradeableCommonFields } from '../../../../model/prebuilt_rule_upgrade/fields'; +import { + BuildingBlockEdit, + buildingBlockSchema, + buildingBlockDeserializer, + buildingBlockSerializer, +} from './fields/building_block'; +import { DescriptionEdit, descriptionSchema } from './fields/description'; +import { + FalsePositivesEdit, + falsePositivesSchema, + falsePositivesSerializer, + falsePositivesDeserializer, +} from './fields/false_positives'; +import { + InvestigationFieldsEdit, + investigationFieldsSchema, + investigationFieldsDeserializer, + investigationFieldsSerializer, +} from './fields/investigation_fields'; +import { + MaxSignalsEdit, + maxSignalsDeserializer, + maxSignalsSchema, + maxSignalsSerializer, +} from './fields/max_signals'; +import { NameEdit, nameSchema } from './fields/name'; +import { NoteEdit, noteSchema } from './fields/note'; +import { ReferencesEdit, referencesSchema, referencesSerializer } from './fields/references'; +import { + RelatedIntegrationsEdit, + relatedIntegrationsSchema, + relatedIntegrationsDeserializer, + relatedIntegrationsSerializer, +} from './fields/related_integrations'; +import { + RequiredFieldsEdit, + requiredFieldsSchema, + requiredFieldsDeserializer, + requiredFieldsSerializer, +} from './fields/required_fields'; +import { + RiskScoreEdit, + riskScoreDeserializer, + riskScoreSchema, + riskScoreSerializer, +} from './fields/risk_score'; +import { + RiskScoreMappingEdit, + riskScoreMappingDeserializer, + riskScoreMappingSerializer, +} from './fields/risk_score_mapping'; +import { + RuleNameOverrideEdit, + ruleNameOverrideDeserializer, + ruleNameOverrideSerializer, + ruleNameOverrideSchema, +} from './fields/rule_name_override'; +import { + RuleScheduleEdit, + ruleScheduleSchema, + ruleScheduleDeserializer, + ruleScheduleSerializer, +} from './fields/rule_schedule'; +import { SetupEdit, setupSchema } from './fields/setup'; +import { SeverityEdit } from './fields/severity'; +import { + SeverityMappingEdit, + severityMappingDeserializer, + severityMappingSerializer, +} from './fields/severity_mapping'; +import { TagsEdit, tagsSchema } from './fields/tags'; +import { ThreatEdit, threatSchema, threatSerializer } from './fields/threat'; +import { + TimelineTemplateEdit, + timelineTemplateDeserializer, + timelineTemplateSchema, + timelineTemplateSerializer, +} from './fields/timeline_template'; +import { + TimestampOverrideEdit, + timestampOverrideDeserializer, + timestampOverrideSerializer, + timestampOverrideSchema, +} from './fields/timestamp_override'; + interface CommonRuleFieldEditProps { fieldName: UpgradeableCommonFields; } +/* eslint-disable-next-line complexity */ export function CommonRuleFieldEdit({ fieldName }: CommonRuleFieldEditProps) { switch (fieldName) { + case 'building_block': + return ( + + ); + case 'description': + return ( + + ); + case 'false_positives': + return ( + + ); + case 'investigation_fields': + return ( + + ); + case 'max_signals': + return ( + + ); case 'name': return ; + case 'note': + return ; + case 'references': + return ( + + ); + case 'related_integrations': + return ( + + ); + case 'required_fields': + return ( + + ); + case 'risk_score': + return ( + + ); + case 'risk_score_mapping': + return ( + + ); + case 'rule_name_override': + return ( + + ); + case 'rule_schedule': + return ( + + ); + case 'setup': + return ; + case 'severity': + return ; + case 'severity_mapping': + return ( + + ); + case 'tags': + return ; + case 'timeline_template': + return ( + + ); + case 'timestamp_override': + return ( + + ); + case 'threat': + return ( + + ); default: return null; // Will be replaced with `assertUnreachable(fieldName)` once all fields are implemented } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/building_block.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/building_block.tsx new file mode 100644 index 0000000000000..3b21ff76f07a8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/building_block.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { Field, UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { BuildingBlockObject } from '../../../../../../../../common/api/detection_engine'; + +export const buildingBlockSchema = { isBuildingBlock: schema.isBuildingBlock } as FormSchema<{ + isBuildingBlock: boolean; +}>; + +export function BuildingBlockEdit(): JSX.Element { + return ; +} + +export function buildingBlockDeserializer(defaultValue: FormData) { + return { + isBuildingBlock: defaultValue.building_block, + }; +} + +export function buildingBlockSerializer(formData: FormData): { + building_block: BuildingBlockObject | undefined; +} { + return { building_block: formData.isBuildingBlock ? { type: 'default' } : undefined }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/description.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/description.tsx new file mode 100644 index 0000000000000..c2d279c0d72e2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/description.tsx @@ -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 React from 'react'; +import type { FormSchema } from '../../../../../../../shared_imports'; +import { Field, UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { RuleDescription } from '../../../../../../../../common/api/detection_engine'; + +export const descriptionSchema = { description: schema.description } as FormSchema<{ + description: RuleDescription; +}>; + +const componentProps = { + euiFieldProps: { + fullWidth: true, + compressed: true, + }, +}; + +export function DescriptionEdit(): JSX.Element { + return ; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/false_positives.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/false_positives.tsx new file mode 100644 index 0000000000000..ddb23732b1871 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/false_positives.tsx @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { isEmpty } from 'lodash'; +import * as i18n from '../../../../../../rule_creation_ui/components/step_about_rule/translations'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { RuleFalsePositiveArray } from '../../../../../../../../common/api/detection_engine'; +import { AddItem } from '../../../../../../rule_creation_ui/components/add_item_form'; + +export const falsePositivesSchema = { falsePositives: schema.falsePositives } as FormSchema<{ + falsePositives: RuleFalsePositiveArray; +}>; + +const componentProps = { + addText: i18n.ADD_FALSE_POSITIVE, +}; + +export function FalsePositivesEdit(): JSX.Element { + return ; +} + +export function falsePositivesDeserializer(defaultValue: FormData) { + return { + falsePositives: defaultValue.false_positives, + }; +} + +export function falsePositivesSerializer(formData: FormData): { + false_positives: RuleFalsePositiveArray; +} { + const falsePositives: RuleFalsePositiveArray = formData.falsePositives; + + return { + /* Remove empty items from the falsePositives array */ + false_positives: falsePositives.filter((item) => !isEmpty(item)), + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/investigation_fields.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/investigation_fields.tsx new file mode 100644 index 0000000000000..971174f455390 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/investigation_fields.tsx @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { + DiffableRule, + InvestigationFields, + RuleFalsePositiveArray, +} from '../../../../../../../../common/api/detection_engine'; +import { MultiSelectFieldsAutocomplete } from '../../../../../../rule_creation_ui/components/multi_select_fields'; +import { useAllEsqlRuleFields } from '../../../../../../rule_creation_ui/hooks'; +import { useDefaultIndexPattern } from '../../../../../hooks/use_default_index_pattern'; +import { useRuleIndexPattern } from '../../../../../../rule_creation_ui/pages/form'; +import { getUseRuleIndexPatternParameters } from '../utils'; + +export const investigationFieldsSchema = { + investigationFields: schema.investigationFields, +} as FormSchema<{ + investigationFields: RuleFalsePositiveArray; +}>; + +interface InvestigationFieldsEditProps { + finalDiffableRule: DiffableRule; +} + +export function InvestigationFieldsEdit({ + finalDiffableRule, +}: InvestigationFieldsEditProps): JSX.Element { + const { type } = finalDiffableRule; + + const defaultIndexPattern = useDefaultIndexPattern(); + const indexPatternParameters = getUseRuleIndexPatternParameters( + finalDiffableRule, + defaultIndexPattern + ); + const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParameters); + + const { fields: investigationFields, isLoading: isInvestigationFieldsLoading } = + useAllEsqlRuleFields({ + esqlQuery: type === 'esql' ? finalDiffableRule.esql_query.query : undefined, + indexPatternsFields: indexPattern.fields, + }); + + return ( + + ); +} + +export function investigationFieldsDeserializer(defaultValue: FormData) { + return { + investigationFields: defaultValue.investigation_fields?.field_names ?? [], + }; +} + +export function investigationFieldsSerializer(formData: FormData): { + investigation_fields: InvestigationFields | undefined; +} { + const hasInvestigationFields = formData.investigationFields.length > 0; + + return { + investigation_fields: hasInvestigationFields + ? { + field_names: formData.investigationFields, + } + : undefined, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/max_signals.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/max_signals.tsx new file mode 100644 index 0000000000000..dd7774eaa5ac4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/max_signals.tsx @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { MaxSignals as MaxSignalsType } from '../../../../../../../../common/api/detection_engine'; +import { DEFAULT_MAX_SIGNALS } from '../../../../../../../../common/constants'; +import { MaxSignals } from '../../../../../../rule_creation_ui/components/max_signals'; + +export const maxSignalsSchema = { maxSignals: schema.maxSignals } as FormSchema<{ + maxSignals: boolean; +}>; + +const componentProps = { + placeholder: DEFAULT_MAX_SIGNALS, +}; + +export function MaxSignalsEdit(): JSX.Element { + return ; +} + +export function maxSignalsDeserializer(defaultValue: FormData) { + return { + maxSignals: defaultValue.max_signals, + }; +} + +export function maxSignalsSerializer(formData: FormData): { + max_signals: MaxSignalsType; +} { + return { + max_signals: Number.isSafeInteger(formData.maxSignals) + ? formData.maxSignals + : DEFAULT_MAX_SIGNALS, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx index 10ae6cffbe50d..d602da90f34b0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/name.tsx @@ -13,16 +13,12 @@ import type { RuleName } from '../../../../../../../../common/api/detection_engi export const nameSchema = { name: schema.name } as FormSchema<{ name: RuleName }>; +const componentProps = { + euiFieldProps: { + fullWidth: true, + }, +}; + export function NameEdit(): JSX.Element { - return ( - - ); + return ; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/note.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/note.tsx new file mode 100644 index 0000000000000..3a560fd28f27c --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/note.tsx @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { FormSchema } from '../../../../../../../shared_imports'; +import { UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { InvestigationGuide } from '../../../../../../../../common/api/detection_engine'; +import * as i18n from '../../../../../../rule_creation_ui/components/step_about_rule/translations'; +import { MarkdownEditorForm } from '../../../../../../../common/components/markdown_editor'; + +export const noteSchema = { note: schema.note } as FormSchema<{ + note: InvestigationGuide; +}>; + +const componentProps = { + placeholder: i18n.ADD_RULE_NOTE_HELP_TEXT, +}; + +export function NoteEdit(): JSX.Element { + return ; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/references.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/references.tsx new file mode 100644 index 0000000000000..afa4fba09d890 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/references.tsx @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { compact } from 'lodash'; +import * as i18n from '../../../../../../rule_creation_ui/components/step_about_rule/translations'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { RuleReferenceArray } from '../../../../../../../../common/api/detection_engine'; +import { AddItem } from '../../../../../../rule_creation_ui/components/add_item_form'; +import { isUrlInvalid } from '../../../../../../../common/utils/validators'; + +export const referencesSchema = { references: schema.references } as FormSchema<{ + references: RuleReferenceArray; +}>; + +const componentProps = { + addText: i18n.ADD_REFERENCE, + validate: isUrlInvalid, +}; + +export function ReferencesEdit(): JSX.Element { + return ; +} + +export function referencesSerializer(formData: FormData): { + references: RuleReferenceArray; +} { + return { + /* Remove empty items from the references array */ + references: compact(formData.references), + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/related_integrations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/related_integrations.tsx new file mode 100644 index 0000000000000..443f0b4bb7752 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/related_integrations.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_define_rule/schema'; +import { RelatedIntegrations } from '../../../../../../rule_creation/components/related_integrations'; +import type { RelatedIntegrationArray } from '../../../../../../../../common/api/detection_engine'; +import { filterOutEmptyRelatedIntegrations } from '../../../../../../rule_creation_ui/pages/rule_creation/helpers'; + +export const relatedIntegrationsSchema = { + relatedIntegrations: schema.relatedIntegrations, +} as FormSchema<{ + relatedIntegrations: RelatedIntegrationArray; +}>; + +export function RelatedIntegrationsEdit(): JSX.Element { + return ; +} + +export function relatedIntegrationsDeserializer(defaultValue: FormData) { + return { + relatedIntegrations: defaultValue.related_integrations, + }; +} + +export function relatedIntegrationsSerializer(formData: FormData): { + related_integrations: RelatedIntegrationArray; +} { + const relatedIntegrations = (formData.relatedIntegrations ?? []) as RelatedIntegrationArray; + + return { + related_integrations: filterOutEmptyRelatedIntegrations(relatedIntegrations), + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/required_fields.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/required_fields.tsx new file mode 100644 index 0000000000000..3e6809e35a4f4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/required_fields.tsx @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_define_rule/schema'; +import type { + DiffableRule, + RequiredFieldInput, +} from '../../../../../../../../common/api/detection_engine'; +import { RequiredFields } from '../../../../../../rule_creation/components/required_fields'; +import { useDefaultIndexPattern } from '../../../../../hooks/use_default_index_pattern'; +import { getUseRuleIndexPatternParameters } from '../utils'; +import { useRuleIndexPattern } from '../../../../../../rule_creation_ui/pages/form'; +import { removeEmptyRequiredFields } from '../../../../../../rule_creation_ui/pages/rule_creation/helpers'; + +export const requiredFieldsSchema = { + requiredFields: schema.requiredFields, +} as FormSchema<{ + requiredFields: RequiredFieldInput[]; +}>; + +interface RequiredFieldsEditProps { + finalDiffableRule: DiffableRule; +} + +export function RequiredFieldsEdit({ finalDiffableRule }: RequiredFieldsEditProps): JSX.Element { + const defaultIndexPattern = useDefaultIndexPattern(); + const indexPatternParameters = getUseRuleIndexPatternParameters( + finalDiffableRule, + defaultIndexPattern + ); + const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParameters); + + return ( + + ); +} + +export function requiredFieldsDeserializer(defaultValue: FormData) { + return { + requiredFields: defaultValue.required_fields, + }; +} + +export function requiredFieldsSerializer(formData: FormData): { + required_fields: RequiredFieldInput[]; +} { + const requiredFields = (formData.requiredFields ?? []) as RequiredFieldInput[]; + return { + required_fields: removeEmptyRequiredFields(requiredFields), + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/risk_score.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/risk_score.tsx new file mode 100644 index 0000000000000..7575213706051 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/risk_score.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 { + type FormData, + type FieldHook, + UseField, + getFieldValidityAndErrorMessage, +} from '../../../../../../../shared_imports'; +import type { RiskScore } from '../../../../../../../../common/api/detection_engine'; +import { DefaultRiskScore } from '../../../../../../rule_creation_ui/components/risk_score_mapping/default_risk_score'; +import { defaultRiskScoreValidator } from '../../../../../../rule_creation_ui/validators/default_risk_score_validator'; + +export const riskScoreSchema = { + riskScore: { + validations: [ + { + validator: ({ path, value }: { path: string; value: unknown }) => + defaultRiskScoreValidator(value, path), + }, + ], + }, +}; + +export function RiskScoreEdit(): JSX.Element { + return ; +} + +interface RiskScoreEditFieldProps { + field: FieldHook; +} + +function RiskScoreEditField({ field }: RiskScoreEditFieldProps) { + const { value, setValue } = field; + const errorMessage = getFieldValidityAndErrorMessage(field).errorMessage ?? undefined; + + return ; +} + +export function riskScoreDeserializer(defaultValue: FormData) { + return { + riskScore: defaultValue.risk_score, + }; +} + +export function riskScoreSerializer(formData: FormData): { + risk_score: RiskScore; +} { + return { + risk_score: formData.riskScore, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/risk_score_mapping.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/risk_score_mapping.tsx new file mode 100644 index 0000000000000..a1e5e3f80630b --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/risk_score_mapping.tsx @@ -0,0 +1,106 @@ +/* + * Copyright 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 type { DataViewFieldBase } from '@kbn/es-query'; +import { type FormData, type FieldHook, UseField } from '../../../../../../../shared_imports'; +import type { + DiffableRule, + RiskScoreMapping, +} from '../../../../../../../../common/api/detection_engine'; +import { RiskScoreOverride } from '../../../../../../rule_creation_ui/components/risk_score_mapping/risk_score_override'; +import { useDefaultIndexPattern } from '../../../../../hooks/use_default_index_pattern'; +import { getUseRuleIndexPatternParameters } from '../utils'; +import { useRuleIndexPattern } from '../../../../../../rule_creation_ui/pages/form'; +import { filterOutEmptyRiskScoreMappingItems } from '../../../../../../rule_creation_ui/pages/rule_creation/helpers'; + +interface RiskScoreMappingEditProps { + finalDiffableRule: DiffableRule; +} + +export function RiskScoreMappingEdit({ finalDiffableRule }: RiskScoreMappingEditProps) { + return ( + + ); +} + +interface RiskScoreMappingFieldProps { + field: FieldHook<{ isMappingChecked: boolean; mapping: RiskScoreMapping }>; + finalDiffableRule: DiffableRule; +} + +function RiskScoreMappingField({ field, finalDiffableRule }: RiskScoreMappingFieldProps) { + const defaultIndexPattern = useDefaultIndexPattern(); + const indexPatternParameters = getUseRuleIndexPatternParameters( + finalDiffableRule, + defaultIndexPattern + ); + const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParameters); + + const { value, setValue } = field; + + const handleToggleMappingChecked = useCallback(() => { + setValue((prevValue) => ({ + ...prevValue, + isMappingChecked: !prevValue.isMappingChecked, + })); + }, [setValue]); + + const handleMappingChange = useCallback( + ([newField]: DataViewFieldBase[]): void => { + const mapping = [ + { + field: newField?.name ?? '', + operator: 'equals' as const, + value: '', + }, + ]; + + setValue((prevValue) => ({ + ...prevValue, + mapping, + })); + }, + [setValue] + ); + + return ( + + ); +} + +export function riskScoreMappingDeserializer(defaultValue: FormData) { + return { + riskScoreMapping: { + isMappingChecked: defaultValue.risk_score_mapping.length > 0, + mapping: defaultValue.risk_score_mapping, + }, + }; +} + +export function riskScoreMappingSerializer(formData: FormData): { + risk_score_mapping: RiskScoreMapping; +} { + return { + risk_score_mapping: formData.riskScoreMapping.isMappingChecked + ? filterOutEmptyRiskScoreMappingItems(formData.riskScoreMapping.mapping) + : [], + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx index 26a2574489b16..1b45bea28880f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_field_edit_form_wrapper.tsx @@ -27,13 +27,13 @@ export type FieldDeserializerFn = ( interface RuleFieldEditFormWrapperProps { component: RuleFieldEditComponent; - ruleFieldFormSchema: FormSchema; + ruleFieldFormSchema?: FormSchema; deserializer?: FieldDeserializerFn; serializer?: (formData: FormData) => FormData; } /** - * FieldFormWrapper component manages form state and renders "Save" and "Cancel" buttons. + * RuleFieldEditFormWrapper component manages form state and renders "Save" and "Cancel" buttons. * * @param {Object} props - Component props. * @param {React.ComponentType} props.component - Field component to be wrapped. diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_name_override.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_name_override.tsx new file mode 100644 index 0000000000000..d133956436505 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_name_override.tsx @@ -0,0 +1,71 @@ +/* + * Copyright 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 type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { + DiffableRule, + RuleNameOverrideObject, +} from '../../../../../../../../common/api/detection_engine'; +import { EsFieldSelectorField } from '../../../../../../rule_creation_ui/components/es_field_selector_field'; +import { useRuleIndexPattern } from '../../../../../../rule_creation_ui/pages/form'; +import { getUseRuleIndexPatternParameters } from '../utils'; +import { useDefaultIndexPattern } from '../../../../../hooks/use_default_index_pattern'; + +export const ruleNameOverrideSchema = { ruleNameOverride: schema.ruleNameOverride } as FormSchema<{ + ruleNameOverride: string; +}>; + +interface RuleNameOverrideEditProps { + finalDiffableRule: DiffableRule; +} + +export function RuleNameOverrideEdit({ + finalDiffableRule, +}: RuleNameOverrideEditProps): JSX.Element { + const defaultIndexPattern = useDefaultIndexPattern(); + const indexPatternParameters = getUseRuleIndexPatternParameters( + finalDiffableRule, + defaultIndexPattern + ); + const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParameters); + + const componentProps = useMemo( + () => ({ + fieldType: 'string', + indices: indexPattern, + isDisabled: isIndexPatternLoading, + }), + [indexPattern, isIndexPatternLoading] + ); + + return ( + + ); +} + +export function ruleNameOverrideDeserializer(defaultValue: FormData) { + return { + ruleNameOverride: defaultValue.rule_name_override?.field_name ?? '', + }; +} + +export function ruleNameOverrideSerializer(formData: FormData): { + rule_name_override: RuleNameOverrideObject | undefined; +} { + return { + rule_name_override: formData.ruleNameOverride + ? { field_name: formData.ruleNameOverride } + : undefined, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule.tsx new file mode 100644 index 0000000000000..12e7bbea9a20a --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/rule_schedule.tsx @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { parseDuration } from '@kbn/alerting-plugin/common'; +import { type FormSchema, type FormData, UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_schedule_rule/schema'; +import type { RuleSchedule } from '../../../../../../../../common/api/detection_engine'; +import { ScheduleItem } from '../../../../../../rule_creation/components/schedule_item_form'; +import { secondsToDurationString } from '../../../../../../../detections/pages/detection_engine/rules/helpers'; + +export const ruleScheduleSchema = { + interval: schema.interval, + from: schema.from, +} as FormSchema<{ + interval: string; + from: string; +}>; + +const componentProps = { + minimumValue: 1, +}; + +export function RuleScheduleEdit(): JSX.Element { + return ( + <> + + + + ); +} + +export function ruleScheduleDeserializer(defaultValue: FormData) { + const lookbackSeconds = parseDuration(defaultValue.rule_schedule.lookback) / 1000; + const lookbackHumanized = secondsToDurationString(lookbackSeconds); + + return { + interval: defaultValue.rule_schedule.interval, + from: lookbackHumanized, + }; +} + +export function ruleScheduleSerializer(formData: FormData): { + rule_schedule: RuleSchedule; +} { + return { + rule_schedule: { + interval: formData.interval, + lookback: formData.from, + }, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/setup.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/setup.tsx new file mode 100644 index 0000000000000..8304641d1b168 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/setup.tsx @@ -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 React from 'react'; +import type { FormSchema } from '../../../../../../../shared_imports'; +import { UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { SetupGuide } from '../../../../../../../../common/api/detection_engine'; +import * as i18n from '../../../../../../rule_creation_ui/components/step_about_rule/translations'; +import { MarkdownEditorForm } from '../../../../../../../common/components/markdown_editor'; + +export const setupSchema = { setup: schema.setup } as FormSchema<{ + setup: SetupGuide; +}>; + +const componentProps = { + placeholder: i18n.ADD_RULE_SETUP_HELP_TEXT, + includePlugins: false, +}; + +export function SetupEdit(): JSX.Element { + return ; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/severity.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/severity.tsx new file mode 100644 index 0000000000000..1a6bf03ea67f1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/severity.tsx @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { type FieldHook, UseField } from '../../../../../../../shared_imports'; +import type { Severity } from '../../../../../../../../common/api/detection_engine'; +import { DefaultSeverity } from '../../../../../../rule_creation_ui/components/severity_mapping/default_severity'; + +export function SeverityEdit(): JSX.Element { + return ; +} + +interface SeverityEditFieldProps { + field: FieldHook; +} + +function SeverityEditField({ field }: SeverityEditFieldProps) { + const { value, setValue } = field; + + return ; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/severity_mapping.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/severity_mapping.tsx new file mode 100644 index 0000000000000..d4206549bfa1e --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/severity_mapping.tsx @@ -0,0 +1,149 @@ +/* + * Copyright 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 type { DataViewFieldBase } from '@kbn/es-query'; +import { type FieldHook, type FormData, UseField } from '../../../../../../../shared_imports'; +import type { + DiffableRule, + Severity, + SeverityMapping, +} from '../../../../../../../../common/api/detection_engine'; +import { SeverityOverride } from '../../../../../../rule_creation_ui/components/severity_mapping/severity_override'; +import { useDefaultIndexPattern } from '../../../../../hooks/use_default_index_pattern'; +import { getUseRuleIndexPatternParameters } from '../utils'; +import { useRuleIndexPattern } from '../../../../../../rule_creation_ui/pages/form'; +import { fillEmptySeverityMappings } from '../../../../../../../detections/pages/detection_engine/rules/helpers'; +import { filterOutEmptySeverityMappingItems } from '../../../../../../rule_creation_ui/pages/rule_creation/helpers'; + +interface SeverityMappingEditProps { + finalDiffableRule: DiffableRule; +} + +export function SeverityMappingEdit({ finalDiffableRule }: SeverityMappingEditProps): JSX.Element { + return ( + + ); +} + +interface SeverityMappingFieldProps { + field: FieldHook<{ + isMappingChecked: boolean; + mapping: SeverityMapping; + }>; + finalDiffableRule: DiffableRule; +} + +function SeverityMappingField({ field, finalDiffableRule }: SeverityMappingFieldProps) { + const defaultIndexPattern = useDefaultIndexPattern(); + const indexPatternParameters = getUseRuleIndexPatternParameters( + finalDiffableRule, + defaultIndexPattern + ); + const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParameters); + + const { value, setValue } = field; + + const handleFieldChange = useCallback( + (index: number, severity: Severity, [newField]: DataViewFieldBase[]): void => { + setValue((prevValue) => { + const newMappingItem: SeverityMapping = [ + { + ...prevValue.mapping[index], + field: newField?.name ?? '', + value: newField != null ? prevValue.mapping[index].value : '', + operator: 'equals', + severity, + }, + ]; + + return { + ...prevValue, + mapping: [ + ...prevValue.mapping.slice(0, index), + ...newMappingItem, + ...prevValue.mapping.slice(index + 1), + ], + }; + }); + }, + [setValue] + ); + + const handleFieldMatchValueChange = useCallback( + (index: number, severity: Severity, newMatchValue: string): void => { + setValue((prevValue) => { + const newMappingItem: SeverityMapping = [ + { + ...prevValue.mapping[index], + field: prevValue.mapping[index].field, + value: + prevValue.mapping[index].field != null && prevValue.mapping[index].field !== '' + ? newMatchValue + : '', + operator: 'equals', + severity, + }, + ]; + + return { + ...prevValue, + mapping: [ + ...prevValue.mapping.slice(0, index), + ...newMappingItem, + ...prevValue.mapping.slice(index + 1), + ], + }; + }); + }, + [setValue] + ); + + const handleSeverityMappingChecked = useCallback(() => { + setValue((prevValue) => ({ + ...prevValue, + isMappingChecked: !prevValue.isMappingChecked, + })); + }, [setValue]); + + return ( + + ); +} + +export function severityMappingDeserializer(defaultValue: FormData) { + return { + severityMapping: { + isMappingChecked: defaultValue.severity_mapping.length > 0, + mapping: fillEmptySeverityMappings(defaultValue.severity_mapping as SeverityMapping), + }, + }; +} + +export function severityMappingSerializer(formData: FormData): { + severity_mapping: SeverityMapping; +} { + return { + severity_mapping: formData.severityMapping.isMappingChecked + ? filterOutEmptySeverityMappingItems(formData.severityMapping.mapping) + : [], + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/tags.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/tags.tsx new file mode 100644 index 0000000000000..063b7f4f48b80 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/tags.tsx @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { FormSchema } from '../../../../../../../shared_imports'; +import { Field, UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { RuleTagArray } from '../../../../../../../../common/api/detection_engine'; + +export const tagsSchema = { tags: schema.tags } as FormSchema<{ name: RuleTagArray }>; + +const componentProps = { + euiFieldProps: { + fullWidth: true, + placeholder: '', + }, +}; + +export function TagsEdit(): JSX.Element { + return ; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threat.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threat.tsx new file mode 100644 index 0000000000000..fbc0541ff50fc --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threat.tsx @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { type FormSchema, type FormData, UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import type { ThreatArray } from '../../../../../../../../common/api/detection_engine'; +import { AddMitreAttackThreat } from '../../../../../../rule_creation_ui/components/mitre'; +import { filterEmptyThreats } from '../../../../../../rule_creation_ui/pages/rule_creation/helpers'; + +export const threatSchema = { threat: schema.threat } as FormSchema<{ threat: ThreatArray }>; + +export function ThreatEdit(): JSX.Element { + return ; +} + +export function threatSerializer(formData: FormData): { + threat: ThreatArray; +} { + return { + threat: filterEmptyThreats(formData.threat).map((singleThreat) => ({ + ...singleThreat, + framework: 'MITRE ATT&CK', + })), + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/timeline_template.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/timeline_template.tsx new file mode 100644 index 0000000000000..1f7ef2eaf05b1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/timeline_template.tsx @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { UseField } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_define_rule/schema'; +import type { TimelineTemplateReference } from '../../../../../../../../common/api/detection_engine'; +import { + PickTimeline, + type FieldValueTimeline, +} from '../../../../../../rule_creation/components/pick_timeline'; + +export const timelineTemplateSchema = { timeline: schema.timeline } as FormSchema<{ + timeline: FieldValueTimeline; +}>; + +export function TimelineTemplateEdit(): JSX.Element { + return ; +} + +export function timelineTemplateDeserializer(defaultValue: FormData) { + return { + timeline: { + id: defaultValue.timeline_template?.timeline_id ?? null, + title: defaultValue.timeline_template?.timeline_title ?? null, + }, + }; +} + +export function timelineTemplateSerializer(formData: FormData): { + timeline_template: TimelineTemplateReference | undefined; +} { + if (!formData.timeline.id) { + return { timeline_template: undefined }; + } + + return { + timeline_template: { + timeline_id: formData.timeline.id, + timeline_title: formData.timeline.title, + }, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/timestamp_override.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/timestamp_override.tsx new file mode 100644 index 0000000000000..a57d538fab47c --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/timestamp_override.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, { useMemo } from 'react'; +import type { FormSchema, FormData } from '../../../../../../../shared_imports'; +import { Field, UseField, useFormData } from '../../../../../../../shared_imports'; +import { schema } from '../../../../../../rule_creation_ui/components/step_about_rule/schema'; +import { EsFieldSelectorField } from '../../../../../../rule_creation_ui/components/es_field_selector_field'; +import { useDefaultIndexPattern } from '../../../../../hooks/use_default_index_pattern'; +import { getUseRuleIndexPatternParameters } from '../utils'; +import { useRuleIndexPattern } from '../../../../../../rule_creation_ui/pages/form'; +import type { + DiffableRule, + TimestampOverrideObject, +} from '../../../../../../../../common/api/detection_engine'; + +export const timestampOverrideSchema = { + timestampOverride: schema.timestampOverride, + timestampOverrideFallbackDisabled: schema.timestampOverrideFallbackDisabled, +} as FormSchema<{ + timestampOverride: string; + timestampOverrideFallbackDisabled: boolean | undefined; +}>; + +interface TimestampOverrideEditProps { + finalDiffableRule: DiffableRule; +} + +export function TimestampOverrideEdit({ + finalDiffableRule, +}: TimestampOverrideEditProps): JSX.Element { + const defaultIndexPattern = useDefaultIndexPattern(); + const indexPatternParameters = getUseRuleIndexPatternParameters( + finalDiffableRule, + defaultIndexPattern + ); + const { indexPattern, isIndexPatternLoading } = useRuleIndexPattern(indexPatternParameters); + + const componentProps = useMemo( + () => ({ + fieldType: 'date', + indices: indexPattern, + isDisabled: isIndexPatternLoading, + }), + [indexPattern, isIndexPatternLoading] + ); + + return ( + <> + + + + ); +} + +function TimestampFallbackDisabled() { + const [formData] = useFormData(); + const { timestampOverride } = formData; + + if (timestampOverride && timestampOverride !== '@timestamp') { + return ; + } + + return null; +} + +export function timestampOverrideDeserializer(defaultValue: FormData) { + return { + timestampOverride: defaultValue.timestamp_override.field_name, + timestampOverrideFallbackDisabled: defaultValue.timestamp_override.fallback_disabled ?? false, + }; +} + +export function timestampOverrideSerializer(formData: FormData): { + timestamp_override: TimestampOverrideObject | undefined; +} { + if (formData.timestampOverride === '') { + return { timestamp_override: undefined }; + } + + return { + timestamp_override: { + field_name: formData.timestampOverride, + fallback_disabled: formData.timestampOverrideFallbackDisabled, + }, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/utils.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/utils.ts new file mode 100644 index 0000000000000..bd78bb5e9ed26 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/utils.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DataSourceType } from '../../../../../../detections/pages/detection_engine/rules/types'; +import { DataSourceType as DataSourceTypeSnakeCase } from '../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../common/api/detection_engine'; + +interface UseRuleIndexPatternParameters { + dataSourceType: DataSourceType; + index: string[]; + dataViewId: string | undefined; +} + +export function getUseRuleIndexPatternParameters( + finalDiffableRule: DiffableRule, + defaultIndexPattern: string[] +): UseRuleIndexPatternParameters { + if (!('data_source' in finalDiffableRule) || !finalDiffableRule.data_source) { + return { + dataSourceType: DataSourceType.IndexPatterns, + index: defaultIndexPattern, + dataViewId: undefined, + }; + } + if (finalDiffableRule.data_source.type === DataSourceTypeSnakeCase.data_view) { + return { + dataSourceType: DataSourceType.DataView, + index: [], + dataViewId: finalDiffableRule.data_source.data_view_id, + }; + } + return { + dataSourceType: DataSourceType.IndexPatterns, + index: finalDiffableRule.data_source.index_patterns, + dataViewId: undefined, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/common_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/common_rule_field_readonly.tsx index bc4f1928ef9ba..6c502b2e41780 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/common_rule_field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/common_rule_field_readonly.tsx @@ -45,7 +45,7 @@ export function CommonRuleFieldReadOnly({ }: CommonRuleFieldReadOnlyProps) { switch (fieldName) { case 'building_block': - return ; + return ; case 'description': return ; case 'investigation_fields': diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/building_block/building_block.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/building_block/building_block.tsx index 84edd7932a2d7..7e64c140e6d70 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/building_block/building_block.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/building_block/building_block.tsx @@ -9,8 +9,17 @@ import React from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import * as ruleDetailsI18n from '../../../../translations'; import { BuildingBlock } from '../../../../rule_about_section'; +import type { BuildingBlockObject } from '../../../../../../../../../common/api/detection_engine'; + +interface BuildingBlockReadOnlyProps { + buildingBlock?: BuildingBlockObject; +} + +export function BuildingBlockReadOnly({ buildingBlock }: BuildingBlockReadOnlyProps) { + if (!buildingBlock || !buildingBlock.type) { + return null; + } -export function BuildingBlockReadOnly() { return ( { + if (threat.length === 0) { + return null; + } + return ( Date: Tue, 12 Nov 2024 11:21:31 +0100 Subject: [PATCH 008/105] [DOCS] Search AI assistant (#199602) --- docs/search/index.asciidoc | 2 +- .../images/ai-assistant-button.png | Bin 0 -> 8159 bytes .../images/ai-assistant-welcome-chat.png | Bin 0 -> 145051 bytes .../search/search-ai-assistant/index.asciidoc | 144 +++++++++++++++++- 4 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 docs/search/search-ai-assistant/images/ai-assistant-button.png create mode 100644 docs/search/search-ai-assistant/images/ai-assistant-welcome-chat.png diff --git a/docs/search/index.asciidoc b/docs/search/index.asciidoc index 4d2ee436327b6..517503772d3ce 100644 --- a/docs/search/index.asciidoc +++ b/docs/search/index.asciidoc @@ -10,7 +10,7 @@ The *Search* space in the {kib} UI contains the following GUI features: * https://www.elastic.co/guide/en/elasticsearch/reference/current/search-application-overview.html[Search Applications] * https://www.elastic.co/guide/en/elasticsearch/reference/current/behavioral-analytics-overview.html[Behavioral Analytics] * <> -* <> +* <> * Dev Tools <> [float] diff --git a/docs/search/search-ai-assistant/images/ai-assistant-button.png b/docs/search/search-ai-assistant/images/ai-assistant-button.png new file mode 100644 index 0000000000000000000000000000000000000000..640d81e32d46b6fc581e33c0bad1f924c7fc3436 GIT binary patch literal 8159 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 XDqF$1;FLcXTmTgXP5D|`>xlmW&1%*v literal 0 HcmV?d00001 diff --git a/docs/search/search-ai-assistant/images/ai-assistant-welcome-chat.png b/docs/search/search-ai-assistant/images/ai-assistant-welcome-chat.png new file mode 100644 index 0000000000000000000000000000000000000000..972ad53599c8ddc81a6b797a54295e91b5568473 GIT binary patch literal 145051 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 FKL80vQ0M>v literal 0 HcmV?d00001 diff --git a/docs/search/search-ai-assistant/index.asciidoc b/docs/search/search-ai-assistant/index.asciidoc index b4013d9ef0ced..146dd22f2ff55 100644 --- a/docs/search/search-ai-assistant/index.asciidoc +++ b/docs/search/search-ai-assistant/index.asciidoc @@ -1,5 +1,143 @@ [role="xpack"] -[[search-assistant]] -== Search AI Assistant +[[search-ai-assistant]] +== AI Assistant -(coming in 8.16.0) \ No newline at end of file +[TIP] +==== +Don't confuse AI Assistant with <>! Use Playground to chat with your data, test and tweak different {es} queries in the Playground UI, and download the code to integrate into your own RAG application. + +Use AI Assistant to get help with Elasticsearch and Kibana tasks directly in the UI. +==== + +.Observability use cases +**** +Refer to the {observability-guide}/obs-ai-assistant.html[Observability documentation] for more information on how to use AI Assistant in Observability contexts. +**** + +*AI Assistant for Observability and Search* uses generative AI to help you with a variety of tasks related to Elasticsearch and Kibana, including: + +1. *Constructing Queries*: Assists you in building queries to search and analyze your data. +2. *Indexing Data*: Guides you on how to index data into Elasticsearch. +3. *Searching Data*: Helps you search for specific data within your Elasticsearch indices. +4. *Using Elasticsearch APIs*: Calls Elasticsearch APIs on your behalf if you need specific operations performed. +5. *Generating Sample Data*: Helps you create sample data for testing and development purposes. +6. *Visualizing and Analyzing Data*: Assists you in creating visualizations and analyzing your data using Kibana. +7. *Explaining ES|QL*: Explains how ES|QL works and help you convert queries from other languages to {ref}/esql.html[ES|QL.] + +[discrete] +[[ai-assistant-requirements]] +=== Requirements + +To use AI Assistant in *Search* contexts, you must have the following: + +* Elastic Stack version 8.16.0, or an Elasticsearch Serverless project. +* A <> to connect to a LLM provider, or a local model. +** You need an account with a third-party generative AI provider, which AI Assistant uses to generate responses, or else you need to host your own local model. +** To set up AI Assistant, you need the `Actions and Connectors : All` <>. +* To use AI Assistant, you need at least the `Elastic AI Assistant : All` and `Actions and Connectors : Read` <>. +* AI Assistant requires {ml-docs}/ml-nlp-elser.html[ELSER], Elastic's proprietary semantic search model. + +[discrete] +[[ai-assistant-data-information]] +=== Your data and AI Assistant + +Elastic does not use customer data for model training. This includes anything you send the model, such as alert or event data, detection rule configurations, queries, and prompts. However, any data you provide to AI Assistant will be processed by the third-party provider you chose when setting up the generative AI connector as part of the assistant setup. + +Elastic does not control third-party tools, and assumes no responsibility or liability for their content, operation, or use, nor for any loss or damage that may arise from your using such tools. Please exercise caution when using AI tools with personal, sensitive, or confidential information. Any data you submit may be used by the provider for AI training or other purposes. There is no guarantee that the provider will keep any information you provide secure or confidential. You should familiarize yourself with the privacy practices and terms of use of any generative AI tools prior to use. + +[discrete] +[[ai-assistant-using]] +=== Using AI Assistant + +To open AI Assistant, select the **AI Assistant** button in the top toolbar in the UI. +You can also use the global search field in the UI to find AI Assistant. +// <> +// TODO link will be available once https://github.com/elastic/kibana/pull/199352 is merged. + +[role="screenshot"] +image::images/ai-assistant-button.png[AI Assistant button,50] + +This opens the AI Assistant chat interface flyout. + +[role="screenshot] +image::images/ai-assistant-welcome-chat.png[AI Assistant Welcome chat,450] + +You can get started by selecting *✨ Suggest* to get some example prompts, or by typing into the chat field. + +[discrete] +[[ai-assistant-add-custom-data]] +=== Add data to the AI Assistant knowledge base + +[NOTE] +==== +This functionality is not available on Elastic Cloud Serverless projects. +==== + +You can improve the relevance of AI Assistant’s responses by indexing your own data into AI Assistant's knowledge base. +AI Assistant uses {ml-docs}/ml-nlp-elser.html[ELSER], Elastic's proprietary semantic search model, to power its search capabilities. + +[discrete] +[[search-ai-assistant-use-the-ui]] +==== Use the UI + +To add external data to the knowledge base in UI: + +. In the AI Assistant UI, select the **Settings** icon: `⋮`. +. Under *Actions*, click **Manage knowledge base**. +. Click the **New entry** button, and choose either: ++ +** **Single entry**: Write content for a single entry in the UI. +** **Bulk import**: Upload a newline delimited JSON (`ndjson`) file containing a list of entries to add to the knowledge base. +Each object should conform to the following format: ++ +[source,json] +---- +{ + "id": "a_unique_human_readable_id", + "text": "Contents of item", +} +---- + +[discrete] +[[observability-ai-assistant-add-data-to-kb]] +==== Use Search connectors + +// Will be updated to mention reindex option for arbitrary indices +// Need to consolidate docs with obs team first + +[NOTE] +==== +This functionality is not available on Elastic Cloud Serverless projects. +==== + +You can ingest external data (GitHub issues, Markdown files, Jira tickets, text files, etc.) into {es} using {ref}/es-connectors.html[Search Connectors]. Connectors sync third party data sources to {es}. + +Supported service types include {ref}/es-connectors-github.html[GitHub], {ref}/es-connectors-slack.html[Slack], {ref}/es-connectors-jira.html[Jira], and more. These can be Elastic managed or self-managed on your own infrastructure. + +To create a connector and make its content available to the AI Assistant knowledge base, follow these steps: + +. *In {kib} UI, go to _Search -> Content -> Connectors_ and follow the instructions to create a new connector.* ++ +For example, if you create a {ref}/es-connectors-github.html[GitHub connector] you must set a `name`, attach it to a new or existing `index`, add your `personal access token` and include the `list of repositories` to synchronize. ++ +TIP: Learn more about configuring and {ref}/es-connectors-usage.html[using connectors] in the Elasticsearch documentation. ++ +. *Create a pipeline and process the data with ELSER.* ++ +To process connector data using {ml-docs}/ml-nlp-elser.html[ELSER], you must create an *ML Inference Pipeline*: ++ +.. Open the previously created connector and select the *Pipelines* tab. +.. Select *Copy and customize* button at the `Unlock your custom pipelines` box. +.. Select *Add Inference Pipeline* button at the `Machine Learning Inference Pipelines` box. +.. Select *ELSER (Elastic Learned Sparse EncodeR)* ML model to add the necessary embeddings to the data. +.. Select the fields that need to be evaluated as part of the inference pipeline. +.. Test and save the inference pipeline and the overall pipeline. +. *Sync data.* ++ +Once the pipeline is set up, perform a *Full Content Sync* of the connector. The inference pipeline will process the data as follows: ++ +* As data comes in, the ELSER model processes the data, creating sparse embeddings for each document. +* If you inspect the ingested documents, you can see how the weights and tokens are added to the `predicted_value` field. +. *Confirm AI Assistant can access the index.* ++ +Ask the AI Assistant a specific question to confirm that the data is available for the AI Assistant knowledge base. From 4a16e910e95d62fd4cc52f4a870147d691b1a681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:28:02 +0000 Subject: [PATCH 009/105] [Inventory][ECO] Use ControlGroupRenderer to filter by entity types (#199174) closes https://github.com/elastic/kibana/issues/193397 https://github.com/user-attachments/assets/e78639a8-bc63-4c5a-8676-0ad9b5f0563e - Added `Entity type` control group field on the Inventory page. - Added `Filters` buttons to the Unified Search bar on the Inventory oage - Moved common hooks from infra to Obs-shared - Refactoring --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-optimizer/limits.yml | 2 +- .../hooks/use_abortable_async.ts | 4 +- .../hooks/use_asset_details_url_state.ts | 2 +- .../infra/public/hooks/use_inventory_views.ts | 3 +- .../hooks/use_metrics_explorer_views.ts | 3 +- ...log_entry_categories_results_url_state.tsx | 2 +- .../use_log_entry_rate_results_url_state.tsx | 2 +- .../infra/public/pages/logs/stream/page.tsx | 3 +- .../search_bar/control_panels_config.ts | 41 +++++ .../search_bar/controls_content.tsx | 13 +- .../components/search_bar/controls_title.tsx | 2 +- .../hosts/hooks/use_hosts_table_url_state.ts | 2 +- .../hosts/hooks/use_logs_search_url_state.ts | 2 +- .../pages/metrics/hosts/hooks/use_tab_id.ts | 2 +- .../metrics/hosts/hooks/use_unified_search.ts | 2 +- .../hooks/use_unified_search_url_state.ts | 2 +- .../use_asset_details_flyout_url_state.ts | 2 +- .../hooks/use_waffle_filters.ts | 2 +- .../hooks/use_waffle_options.ts | 2 +- .../inventory_view/hooks/use_waffle_time.ts | 2 +- .../metric_detail/hooks/use_metrics_time.ts | 2 +- .../inventory/common/entities.ts | 25 +-- .../inventory/common/entitites.test.ts | 57 ------ .../inventory/e2e/cypress/e2e/home.cy.ts | 33 ++-- .../inventory/kibana.jsonc | 2 +- .../public/components/app_root/index.tsx | 12 +- .../badge_filter_with_popover.test.tsx | 28 +-- .../badge_filter_with_popover/index.tsx | 121 +++++++------ .../entities_grid/entities_grid.stories.tsx | 2 - .../public/components/entities_grid/index.tsx | 13 +- .../grouped_entities_grid.tsx | 71 ++++---- .../components/grouped_inventory/index.tsx | 36 ++-- .../inventory_group_accordion.test.tsx | 8 +- .../inventory_group_accordion.tsx | 26 +-- .../components/search_bar/control_groups.tsx | 98 +++++++++++ .../search_bar/entity_types_controls.tsx | 67 ------- .../public/components/search_bar/index.tsx | 81 +++------ .../index.tsx} | 58 +++--- .../public/hooks/use_discover_redirect.ts | 36 ++-- .../hooks/use_unified_search_context.ts | 166 ++++++++++++++++++ .../public/hooks/use_unified_search_url.ts | 100 +++++++++++ .../public/pages/inventory_page/index.tsx | 30 +--- .../inventory/public/routes/config.tsx | 11 +- .../services/telemetry/telemetry_client.ts | 7 - .../services/telemetry/telemetry_events.ts | 34 ---- .../telemetry/telemetry_service.test.ts | 22 --- .../public/services/telemetry/types.ts | 8 - .../routes/entities/get_entity_groups.ts | 25 +-- .../routes/entities/get_latest_entities.ts | 15 +- .../entities/get_latest_entities_alerts.ts | 8 +- .../inventory/server/routes/entities/route.ts | 15 +- .../inventory/tsconfig.json | 2 + .../components/log_stream/log_stream.tsx | 2 +- .../public/utils/use_kibana_query_settings.ts | 31 ---- .../hooks/use_control_panels_url_state.ts | 158 +++++++---------- .../public/hooks/use_kibana_query_settings.ts | 0 .../public/hooks/use_url_state.ts | 24 ++- .../observability_shared/public/index.ts | 4 + .../observability_shared/tsconfig.json | 1 + .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 62 files changed, 783 insertions(+), 757 deletions(-) create mode 100644 x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/control_panels_config.ts delete mode 100644 x-pack/plugins/observability_solution/inventory/common/entitites.test.ts create mode 100644 x-pack/plugins/observability_solution/inventory/public/components/search_bar/control_groups.tsx delete mode 100644 x-pack/plugins/observability_solution/inventory/public/components/search_bar/entity_types_controls.tsx rename x-pack/plugins/observability_solution/inventory/public/components/{grouped_inventory/unified_inventory.tsx => unified_inventory/index.tsx} (71%) create mode 100644 x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_context.ts create mode 100644 x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_url.ts delete mode 100644 x-pack/plugins/observability_solution/logs_shared/public/utils/use_kibana_query_settings.ts rename x-pack/plugins/observability_solution/{infra/public/pages/metrics/hosts => observability_shared/public}/hooks/use_control_panels_url_state.ts (63%) rename x-pack/plugins/observability_solution/{infra => observability_shared}/public/hooks/use_kibana_query_settings.ts (100%) rename x-pack/plugins/observability_solution/{infra => observability_shared}/public/hooks/use_url_state.ts (81%) diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index df8a077e844f6..aca3a1a0c3c99 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -119,7 +119,7 @@ pageLoadAssetSize: observabilityAiAssistantManagement: 19279 observabilityLogsExplorer: 46650 observabilityOnboarding: 19573 - observabilityShared: 80000 + observabilityShared: 111036 osquery: 107090 painlessLab: 179748 presentationPanel: 55463 diff --git a/x-pack/packages/observability/observability_utils/hooks/use_abortable_async.ts b/x-pack/packages/observability/observability_utils/hooks/use_abortable_async.ts index 433ca877b0f62..477d765ef7a7f 100644 --- a/x-pack/packages/observability/observability_utils/hooks/use_abortable_async.ts +++ b/x-pack/packages/observability/observability_utils/hooks/use_abortable_async.ts @@ -54,7 +54,9 @@ export function useAbortableAsync( }) .catch((err) => { setValue(undefined); - setError(err); + if (!controller.signal.aborted) { + setError(err); + } }) .finally(() => setLoading(false)); } else { diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_asset_details_url_state.ts b/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_asset_details_url_state.ts index d0694ef7f207f..3199cbf70c0be 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_asset_details_url_state.ts +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/hooks/use_asset_details_url_state.ts @@ -15,8 +15,8 @@ import { ALERT_STATUS_RECOVERED, ALERT_STATUS_UNTRACKED, } from '@kbn/rule-data-utils'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; import { ContentTabIds } from '../types'; -import { useUrlState } from '../../../hooks/use_url_state'; import { ASSET_DETAILS_URL_STATE_KEY } from '../constants'; import { ALERT_STATUS_ALL } from '../../shared/alerts/constants'; diff --git a/x-pack/plugins/observability_solution/infra/public/hooks/use_inventory_views.ts b/x-pack/plugins/observability_solution/infra/public/hooks/use_inventory_views.ts index 38f3b19604102..d334baa0e5fdf 100644 --- a/x-pack/plugins/observability_solution/infra/public/hooks/use_inventory_views.ts +++ b/x-pack/plugins/observability_solution/infra/public/hooks/use_inventory_views.ts @@ -9,7 +9,7 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { useUiTracker } from '@kbn/observability-shared-plugin/public'; +import { useUiTracker, useUrlState } from '@kbn/observability-shared-plugin/public'; import { MutationContext, SavedViewResult, @@ -23,7 +23,6 @@ import { } from '../../common/http_api/latest'; import type { InventoryView } from '../../common/inventory_views'; import { useKibanaContextForPlugin } from './use_kibana'; -import { useUrlState } from './use_url_state'; import { useSavedViewsNotifier } from './use_saved_views_notifier'; import { useSourceContext } from '../containers/metrics_source'; diff --git a/x-pack/plugins/observability_solution/infra/public/hooks/use_metrics_explorer_views.ts b/x-pack/plugins/observability_solution/infra/public/hooks/use_metrics_explorer_views.ts index 6d652af02a136..ddf27da96e1a7 100644 --- a/x-pack/plugins/observability_solution/infra/public/hooks/use_metrics_explorer_views.ts +++ b/x-pack/plugins/observability_solution/infra/public/hooks/use_metrics_explorer_views.ts @@ -9,7 +9,7 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { useUiTracker } from '@kbn/observability-shared-plugin/public'; +import { useUiTracker, useUrlState } from '@kbn/observability-shared-plugin/public'; import { MutationContext, @@ -23,7 +23,6 @@ import { UpdateMetricsExplorerViewAttributesRequestPayload, } from '../../common/http_api/latest'; import { MetricsExplorerView } from '../../common/metrics_explorer_views'; -import { useUrlState } from './use_url_state'; import { useSavedViewsNotifier } from './use_saved_views_notifier'; import { useSourceContext } from '../containers/metrics_source'; import { useKibanaContextForPlugin } from './use_kibana'; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results_url_state.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results_url_state.tsx index 169000aa3801f..f219757da8514 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results_url_state.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results_url_state.tsx @@ -9,7 +9,7 @@ import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { useUrlState } from '../../../hooks/use_url_state'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; import { useKibanaTimefilterTime, useSyncKibanaTimeFilterTime, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/use_log_entry_rate_results_url_state.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/use_log_entry_rate_results_url_state.tsx index 1130c8dca9be2..f669d82f76f0f 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/use_log_entry_rate_results_url_state.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/log_entry_rate/use_log_entry_rate_results_url_state.tsx @@ -12,8 +12,8 @@ import moment from 'moment'; import * as rt from 'io-ts'; import type { TimeRange as KibanaTimeRange } from '@kbn/es-query'; import { decodeOrThrow } from '@kbn/io-ts-utils'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; import { TimeRange } from '../../../../common/time/time_range'; -import { useUrlState } from '../../../hooks/use_url_state'; import { useKibanaTimefilterTime, useSyncKibanaTimeFilterTime, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page.tsx index 33ff9300c4d94..706fb7811fa78 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/stream/page.tsx @@ -6,7 +6,7 @@ */ import { EuiErrorBoundary } from '@elastic/eui'; -import { useTrackPageview } from '@kbn/observability-shared-plugin/public'; +import { useKibanaQuerySettings, useTrackPageview } from '@kbn/observability-shared-plugin/public'; import React from 'react'; import { useLogViewContext } from '@kbn/logs-shared-plugin/public'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; @@ -14,7 +14,6 @@ import { useLogsBreadcrumbs } from '../../../hooks/use_logs_breadcrumbs'; import { LogStreamPageStateProvider } from '../../../observability_logs/log_stream_page/state'; import { streamTitle } from '../../../translations'; import { useKbnUrlStateStorageFromRouterContext } from '../../../containers/kbn_url_state_context'; -import { useKibanaQuerySettings } from '../../../hooks/use_kibana_query_settings'; import { ConnectedStreamPageContent } from './page_content'; export const StreamPage = () => { diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/control_panels_config.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/control_panels_config.ts new file mode 100644 index 0000000000000..75e2469974768 --- /dev/null +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/control_panels_config.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ControlPanels } from '@kbn/observability-shared-plugin/public'; + +export const availableControlsPanels = { + HOST_OS_NAME: 'host.os.name', + CLOUD_PROVIDER: 'cloud.provider', + SERVICE_NAME: 'service.name', +}; + +export const controlPanelConfigs: ControlPanels = { + [availableControlsPanels.HOST_OS_NAME]: { + order: 0, + width: 'medium', + grow: false, + type: 'optionsListControl', + fieldName: availableControlsPanels.HOST_OS_NAME, + title: 'Operating System', + }, + [availableControlsPanels.CLOUD_PROVIDER]: { + order: 1, + width: 'medium', + grow: false, + type: 'optionsListControl', + fieldName: availableControlsPanels.CLOUD_PROVIDER, + title: 'Cloud Provider', + }, + [availableControlsPanels.SERVICE_NAME]: { + order: 2, + width: 'medium', + grow: false, + type: 'optionsListControl', + fieldName: availableControlsPanels.SERVICE_NAME, + title: 'Service Name', + }, +}; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/controls_content.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/controls_content.tsx index 2ee6aa762e77c..847d0e05183a7 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/controls_content.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/controls_content.tsx @@ -5,18 +5,19 @@ * 2.0. */ -import React, { useCallback, useEffect, useRef } from 'react'; import { ControlGroupRenderer, ControlGroupRendererApi, - DataControlApi, ControlGroupRuntimeState, + DataControlApi, } from '@kbn/controls-plugin/public'; -import type { Filter, Query, TimeRange } from '@kbn/es-query'; import { DataView } from '@kbn/data-views-plugin/public'; -import { Subscription } from 'rxjs'; +import type { Filter, Query, TimeRange } from '@kbn/es-query'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { useControlPanels } from '../../hooks/use_control_panels_url_state'; +import { useControlPanels } from '@kbn/observability-shared-plugin/public'; +import React, { useCallback, useEffect, useRef } from 'react'; +import { Subscription } from 'rxjs'; +import { controlPanelConfigs } from './control_panels_config'; import { ControlTitle } from './controls_title'; interface Props { @@ -34,7 +35,7 @@ export const ControlsContent: React.FC = ({ timeRange, onFiltersChange, }) => { - const [controlPanels, setControlPanels] = useControlPanels(dataView); + const [controlPanels, setControlPanels] = useControlPanels(controlPanelConfigs, dataView); const subscriptions = useRef(new Subscription()); const getInitialInput = useCallback( diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/controls_title.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/controls_title.tsx index 7202985dbb6bb..b5b45e0d3979a 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/controls_title.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/search_bar/controls_title.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { EuiFormLabel, EuiText, EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { availableControlsPanels } from '../../hooks/use_control_panels_url_state'; import { Popover } from '../common/popover'; +import { availableControlsPanels } from './control_panels_config'; const helpMessages = { [availableControlsPanels.SERVICE_NAME]: ( diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_hosts_table_url_state.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_hosts_table_url_state.ts index c3a5117c18efe..3c2569da620c7 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_hosts_table_url_state.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_hosts_table_url_state.ts @@ -12,7 +12,7 @@ import { constant, identity } from 'fp-ts/lib/function'; import useLocalStorage from 'react-use/lib/useLocalStorage'; import deepEqual from 'fast-deep-equal'; import { useReducer } from 'react'; -import { useUrlState } from '../../../../hooks/use_url_state'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; import { DEFAULT_PAGE_SIZE, LOCAL_STORAGE_PAGE_SIZE_KEY } from '../constants'; export const GET_DEFAULT_TABLE_PROPERTIES: TableProperties = { diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_logs_search_url_state.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_logs_search_url_state.ts index d40004e325a60..e2caa050132d3 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_logs_search_url_state.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_logs_search_url_state.ts @@ -9,7 +9,7 @@ import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { useUrlState } from '../../../../hooks/use_url_state'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; const DEFAULT_QUERY = { language: 'kuery', diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_tab_id.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_tab_id.ts index ec5d897751481..4e9215158c696 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_tab_id.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_tab_id.ts @@ -9,7 +9,7 @@ import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { useUrlState } from '../../../../hooks/use_url_state'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; const TAB_ID_URL_STATE_KEY = 'tabId'; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_unified_search.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_unified_search.ts index 8912ec480e3b7..8a7302da1a223 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_unified_search.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_unified_search.ts @@ -10,9 +10,9 @@ import { buildEsQuery, Filter, fromKueryExpression, TimeRange, type Query } from import { Subscription, map, tap } from 'rxjs'; import deepEqual from 'fast-deep-equal'; import useEffectOnce from 'react-use/lib/useEffectOnce'; +import { useKibanaQuerySettings } from '@kbn/observability-shared-plugin/public'; import { useSearchSessionContext } from '../../../../hooks/use_search_session'; import { parseDateRange } from '../../../../utils/datemath'; -import { useKibanaQuerySettings } from '../../../../hooks/use_kibana_query_settings'; import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; import { telemetryTimeRangeFormatter } from '../../../../../common/formatters/telemetry_time_range'; import { useMetricsDataViewContext } from '../../../../containers/metrics_source'; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_unified_search_url_state.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_unified_search_url_state.ts index 4c96fd93524be..c7bcf09271a3e 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_unified_search_url_state.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_unified_search_url_state.ts @@ -14,7 +14,7 @@ import { constant, identity } from 'fp-ts/lib/function'; import { enumeration } from '@kbn/securitysolution-io-ts-types'; import { FilterStateStore } from '@kbn/es-query'; import useLocalStorage from 'react-use/lib/useLocalStorage'; -import { useUrlState } from '../../../../hooks/use_url_state'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; import { useKibanaTimefilterTime, useSyncKibanaTimeFilterTime, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_asset_details_flyout_url_state.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_asset_details_flyout_url_state.ts index bbce5a9f90579..8878dead99d05 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_asset_details_flyout_url_state.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_asset_details_flyout_url_state.ts @@ -9,7 +9,7 @@ import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; -import { useUrlState } from '../../../../hooks/use_url_state'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; export const GET_DEFAULT_PROPERTIES: AssetDetailsFlyoutProperties = { detailsItemId: null, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_filters.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_filters.ts index 94ad32c4e3097..7372fbcfdd737 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_filters.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_filters.ts @@ -12,12 +12,12 @@ import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import createContainter from 'constate'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; import { type InventoryFiltersState, inventoryFiltersStateRT, } from '../../../../../common/inventory_views'; import { useAlertPrefillContext } from '../../../../alerting/use_alert_prefill'; -import { useUrlState } from '../../../../hooks/use_url_state'; import { useMetricsDataViewContext } from '../../../../containers/metrics_source'; import { convertKueryToElasticSearchQuery } from '../../../../utils/kuery'; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts index 38dd4f0bf3617..41b91bce9c4ee 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_options.ts @@ -11,6 +11,7 @@ import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import createContainer from 'constate'; import type { InventoryItemType } from '@kbn/metrics-data-access-plugin/common'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; import { InventoryViewOptions } from '../../../../../common/inventory_views/types'; import { type InventoryLegendOptions, @@ -24,7 +25,6 @@ import type { SnapshotGroupBy, SnapshotCustomMetricInput, } from '../../../../../common/http_api/snapshot_api'; -import { useUrlState } from '../../../../hooks/use_url_state'; export const DEFAULT_LEGEND: WaffleLegendOptions = { palette: 'cool', diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_time.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_time.ts index 670f8645fc485..a7aadb731a750 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_time.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/hooks/use_waffle_time.ts @@ -12,7 +12,7 @@ import { fold } from 'fp-ts/lib/Either'; import DateMath from '@kbn/datemath'; import { constant, identity } from 'fp-ts/lib/function'; import createContainer from 'constate'; -import { useUrlState } from '../../../../hooks/use_url_state'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; import { useKibanaTimefilterTime } from '../../../../hooks/use_kibana_timefilter_time'; export const DEFAULT_WAFFLE_TIME_STATE: WaffleTimeState = { currentTime: Date.now(), diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts index 7c61778dce74e..b36a1a1cd1c5d 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/metric_detail/hooks/use_metrics_time.ts @@ -13,8 +13,8 @@ import * as rt from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; import { replaceStateKeyInQueryString } from '../../../../../common/url_state_storage_service'; -import { useUrlState } from '../../../../hooks/use_url_state'; const parseRange = (range: MetricsTimeInput) => { const parsedFrom = dateMath.parse(range.from.toString()); diff --git a/x-pack/plugins/observability_solution/inventory/common/entities.ts b/x-pack/plugins/observability_solution/inventory/common/entities.ts index 507d9d492c0f7..3a9684a38254a 100644 --- a/x-pack/plugins/observability_solution/inventory/common/entities.ts +++ b/x-pack/plugins/observability_solution/inventory/common/entities.ts @@ -80,29 +80,6 @@ export const ENTITIES_LATEST_ALIAS = entitiesAliasPattern({ dataset: ENTITY_LATEST, }); -const entityArrayRt = t.array(t.string); -export const entityTypesRt = new t.Type( - 'entityTypesRt', - entityArrayRt.is, - (input, context) => { - if (typeof input === 'string') { - const arr = input.split(','); - const validation = entityArrayRt.decode(arr); - if (isRight(validation)) { - return t.success(validation.right); - } - } else if (Array.isArray(input)) { - const validation = entityArrayRt.decode(input); - if (isRight(validation)) { - return t.success(validation.right); - } - } - - return t.failure(input, context); - }, - (arr) => arr.join() -); - export interface Entity { [ENTITY_LAST_SEEN]: string; [ENTITY_ID]: string; @@ -117,7 +94,7 @@ export interface Entity { export type EntityGroup = { count: number; } & { - [key: string]: any; + [key: string]: string; }; export type InventoryEntityLatest = z.infer & { diff --git a/x-pack/plugins/observability_solution/inventory/common/entitites.test.ts b/x-pack/plugins/observability_solution/inventory/common/entitites.test.ts deleted file mode 100644 index c923bda530746..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/common/entitites.test.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { isLeft, isRight } from 'fp-ts/lib/Either'; -import { entityTypesRt } from './entities'; - -const validate = (input: unknown) => entityTypesRt.decode(input); - -describe('entityTypesRt codec', () => { - it('should validate a valid string of entity types', () => { - const input = 'service,host,container'; - const result = validate(input); - expect(isRight(result)).toBe(true); - if (isRight(result)) { - expect(result.right).toEqual(['service', 'host', 'container']); - } - }); - - it('should validate a valid array of entity types', () => { - const input = ['service', 'host', 'container']; - const result = validate(input); - expect(isRight(result)).toBe(true); - if (isRight(result)) { - expect(result.right).toEqual(['service', 'host', 'container']); - } - }); - - it('should fail validation when input is not a string or array', () => { - const input = 123; - const result = validate(input); - expect(isLeft(result)).toBe(true); - }); - - it('should validate an empty array as valid', () => { - const input: unknown[] = []; - const result = validate(input); - expect(isRight(result)).toBe(true); - if (isRight(result)) { - expect(result.right).toEqual([]); - } - }); - - it('should serialize a valid array back to a string', () => { - const input = ['service', 'host']; - const serialized = entityTypesRt.encode(input); - expect(serialized).toBe('service,host'); - }); - - it('should serialize an empty array back to an empty string', () => { - const input: string[] = []; - const serialized = entityTypesRt.encode(input); - expect(serialized).toBe(''); - }); -}); diff --git a/x-pack/plugins/observability_solution/inventory/e2e/cypress/e2e/home.cy.ts b/x-pack/plugins/observability_solution/inventory/e2e/cypress/e2e/home.cy.ts index d24953c38eb13..9c9011609740b 100644 --- a/x-pack/plugins/observability_solution/inventory/e2e/cypress/e2e/home.cy.ts +++ b/x-pack/plugins/observability_solution/inventory/e2e/cypress/e2e/home.cy.ts @@ -165,16 +165,17 @@ describe('Home page', () => { cy.intercept('GET', '/internal/entities/managed/enablement', { fixture: 'eem_enabled.json', }).as('getEEMStatus'); + cy.intercept('POST', 'internal/controls/optionsList/entities-*-latest').as( + 'entityTypeControlGroupOptions' + ); cy.intercept('GET', '/internal/inventory/entities?**').as('getEntities'); cy.intercept('GET', '/internal/inventory/entities/group_by/**').as('getGroups'); cy.visitKibana('/app/inventory'); cy.wait('@getEEMStatus'); - cy.getByTestSubj('entityTypesFilterComboBox') - .click() - .getByTestSubj('entityTypesFilterserviceOption') - .click(); + cy.getByTestSubj('optionsList-control-entity.type').click(); + cy.wait('@entityTypeControlGroupOptions'); + cy.getByTestSubj('optionsList-control-selection-service').click(); cy.wait('@getGroups'); - cy.contains('service'); cy.getByTestSubj('inventoryGroupTitle_entity.type_service').click(); cy.wait('@getEntities'); cy.get('server1').should('not.exist'); @@ -188,16 +189,17 @@ describe('Home page', () => { cy.intercept('GET', '/internal/entities/managed/enablement', { fixture: 'eem_enabled.json', }).as('getEEMStatus'); + cy.intercept('POST', 'internal/controls/optionsList/entities-*-latest').as( + 'entityTypeControlGroupOptions' + ); cy.intercept('GET', '/internal/inventory/entities?**').as('getEntities'); cy.intercept('GET', '/internal/inventory/entities/group_by/**').as('getGroups'); cy.visitKibana('/app/inventory'); cy.wait('@getEEMStatus'); - cy.getByTestSubj('entityTypesFilterComboBox') - .click() - .getByTestSubj('entityTypesFilterhostOption') - .click(); + cy.getByTestSubj('optionsList-control-entity.type').click(); + cy.wait('@entityTypeControlGroupOptions'); + cy.getByTestSubj('optionsList-control-selection-host').click(); cy.wait('@getGroups'); - cy.contains('host'); cy.getByTestSubj('inventoryGroupTitle_entity.type_host').click(); cy.wait('@getEntities'); cy.contains('server1'); @@ -211,16 +213,17 @@ describe('Home page', () => { cy.intercept('GET', '/internal/entities/managed/enablement', { fixture: 'eem_enabled.json', }).as('getEEMStatus'); + cy.intercept('POST', 'internal/controls/optionsList/entities-*-latest').as( + 'entityTypeControlGroupOptions' + ); cy.intercept('GET', '/internal/inventory/entities?**').as('getEntities'); cy.intercept('GET', '/internal/inventory/entities/group_by/**').as('getGroups'); cy.visitKibana('/app/inventory'); cy.wait('@getEEMStatus'); - cy.getByTestSubj('entityTypesFilterComboBox') - .click() - .getByTestSubj('entityTypesFiltercontainerOption') - .click(); + cy.getByTestSubj('optionsList-control-entity.type').click(); + cy.wait('@entityTypeControlGroupOptions'); + cy.getByTestSubj('optionsList-control-selection-container').click(); cy.wait('@getGroups'); - cy.contains('container'); cy.getByTestSubj('inventoryGroupTitle_entity.type_container').click(); cy.wait('@getEntities'); cy.contains('server1').should('not.exist'); diff --git a/x-pack/plugins/observability_solution/inventory/kibana.jsonc b/x-pack/plugins/observability_solution/inventory/kibana.jsonc index e7cc398c9c655..e6e7c5f2fa2f8 100644 --- a/x-pack/plugins/observability_solution/inventory/kibana.jsonc +++ b/x-pack/plugins/observability_solution/inventory/kibana.jsonc @@ -21,7 +21,7 @@ "ruleRegistry", "share" ], - "requiredBundles": ["kibanaReact"], + "requiredBundles": ["kibanaReact","controls"], "optionalPlugins": ["spaces", "cloud"], "extraPublicDirs": [] } diff --git a/x-pack/plugins/observability_solution/inventory/public/components/app_root/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/app_root/index.tsx index 6bec4335c7193..52f46268da2ef 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/app_root/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/app_root/index.tsx @@ -12,12 +12,12 @@ import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app'; import { RouteRenderer, RouterProvider } from '@kbn/typed-react-router-config'; import React from 'react'; import { InventoryContextProvider } from '../../context/inventory_context_provider'; -import { InventorySearchBarContextProvider } from '../../context/inventory_search_bar_context_provider'; +import { KibanaEnvironment } from '../../hooks/use_kibana'; +import { UnifiedSearchProvider } from '../../hooks/use_unified_search_context'; import { inventoryRouter } from '../../routes/config'; import { InventoryServices } from '../../services/types'; import { InventoryStartDependencies } from '../../types'; import { HeaderActionMenuItems } from './header_action_menu'; -import { KibanaEnvironment } from '../../hooks/use_kibana'; export function AppRoot({ coreStart, @@ -43,12 +43,12 @@ export function AppRoot({ return ( - - + + - - + + ); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/badge_filter_with_popover.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/badge_filter_with_popover.test.tsx index 6018b66d37991..f3c518ef49b16 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/badge_filter_with_popover.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/badge_filter_with_popover.test.tsx @@ -5,11 +5,11 @@ * 2.0. */ +import { copyToClipboard } from '@elastic/eui'; +import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; +import { fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; -import { render, fireEvent, screen } from '@testing-library/react'; import { BadgeFilterWithPopover } from '.'; -import { EuiThemeProvider, copyToClipboard } from '@elastic/eui'; -import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; jest.mock('@elastic/eui', () => ({ ...jest.requireActual('@elastic/eui'), @@ -17,10 +17,8 @@ jest.mock('@elastic/eui', () => ({ })); describe('BadgeFilterWithPopover', () => { - const mockOnFilter = jest.fn(); const field = ENTITY_TYPE; const value = 'host'; - const label = 'Host'; const popoverContentDataTestId = 'inventoryBadgeFilterWithPopoverContent'; const popoverContentTitleTestId = 'inventoryBadgeFilterWithPopoverTitle'; @@ -28,32 +26,16 @@ describe('BadgeFilterWithPopover', () => { jest.clearAllMocks(); }); - it('renders the badge with the correct label', () => { - render( - , - { wrapper: EuiThemeProvider } - ); - expect(screen.queryByText(label)).toBeInTheDocument(); - expect(screen.getByText(label).textContent).toBe(label); - }); - it('opens the popover when the badge is clicked', () => { - render(); + render(); expect(screen.queryByTestId(popoverContentDataTestId)).not.toBeInTheDocument(); fireEvent.click(screen.getByText(value)); expect(screen.queryByTestId(popoverContentDataTestId)).toBeInTheDocument(); expect(screen.queryByTestId(popoverContentTitleTestId)?.textContent).toBe(`${field}:${value}`); }); - it('calls onFilter when the "Filter for" button is clicked', () => { - render(); - fireEvent.click(screen.getByText(value)); - fireEvent.click(screen.getByTestId('inventoryBadgeFilterWithPopoverFilterForButton')); - expect(mockOnFilter).toHaveBeenCalled(); - }); - it('copies value to clipboard when the "Copy value" button is clicked', () => { - render(); + render(); fireEvent.click(screen.getByText(value)); fireEvent.click(screen.getByTestId('inventoryBadgeFilterWithPopoverCopyValueButton')); expect(copyToClipboard).toHaveBeenCalledWith(value); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/index.tsx index d1e952e189d6e..83e0bb02e6d8d 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/badge_filter_with_popover/index.tsx @@ -8,28 +8,29 @@ import { EuiBadge, EuiButtonEmpty, - EuiFlexGrid, EuiFlexGroup, EuiFlexItem, EuiPopover, EuiPopoverFooter, + EuiPopoverTitle, copyToClipboard, useEuiTheme, } from '@elastic/eui'; import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; +import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; import React, { useState } from 'react'; +import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; interface Props { field: string; value: string; - label?: string; - onFilter: () => void; } -export function BadgeFilterWithPopover({ field, value, onFilter, label }: Props) { +export function BadgeFilterWithPopover({ field, value }: Props) { const [isOpen, setIsOpen] = useState(false); const theme = useEuiTheme(); + const { addFilter } = useUnifiedSearchContext(); return ( - {label || value} + {value} } isOpen={isOpen} closePopover={() => setIsOpen(false)} + panelPaddingSize="s" > - - - - - {field}: - - - - {value} - - - + + + + + + {field}: + + + + {value} + + + + + + + { + addFilter({ fieldName: ENTITY_TYPE, operation: '+', value }); + }} + > + {i18n.translate('xpack.inventory.badgeFilterWithPopover.filterForButtonEmptyLabel', { + defaultMessage: 'Filter for', + })} + + + + { + addFilter({ fieldName: ENTITY_TYPE, operation: '-', value }); + }} + > + {i18n.translate('xpack.inventory.badgeFilterWithPopover.filterForButtonEmptyLabel', { + defaultMessage: 'Filter out', + })} + + + - - - - {i18n.translate('xpack.inventory.badgeFilterWithPopover.filterForButtonEmptyLabel', { - defaultMessage: 'Filter for', - })} - - - - copyToClipboard(value)} - > - {i18n.translate('xpack.inventory.badgeFilterWithPopover.copyValueButtonEmptyLabel', { - defaultMessage: 'Copy value', - })} - - - + copyToClipboard(value)} + > + {i18n.translate('xpack.inventory.badgeFilterWithPopover.copyValueButtonEmptyLabel', { + defaultMessage: 'Copy value', + })} + ); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entities_grid.stories.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entities_grid.stories.tsx index 047c2e73d0d3e..a3f2834934cd8 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entities_grid.stories.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entities_grid.stories.tsx @@ -77,7 +77,6 @@ export const Grid: Story = (args) => { onChangePage={setPageIndex} onChangeSort={setSort} pageIndex={pageIndex} - onFilterByType={(selectedEntityType) => updateArgs({ entityType: selectedEntityType })} /> @@ -100,7 +99,6 @@ export const EmptyGrid: Story = (args) => { onChangePage={setPageIndex} onChangeSort={setSort} pageIndex={pageIndex} - onFilterByType={() => {}} /> ); }; diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx index 7819e944c486d..7ca29f7820332 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx @@ -40,7 +40,6 @@ interface Props { pageIndex: number; onChangeSort: (sorting: EuiDataGridSorting['columns'][0]) => void; onChangePage: (nextPage: number) => void; - onFilterByType: (entityType: string) => void; } const PAGE_SIZE = 20; @@ -53,7 +52,6 @@ export function EntitiesGrid({ pageIndex, onChangePage, onChangeSort, - onFilterByType, }: Props) { const { getDiscoverRedirectUrl } = useDiscoverRedirect(); @@ -98,14 +96,7 @@ export function EntitiesGrid({ return entity?.alertsCount ? : null; case ENTITY_TYPE: - return ( - onFilterByType(entityType)} - /> - ); + return ; case ENTITY_LAST_SEEN: return ( { - return inventoryAPIClient.fetch('GET /internal/inventory/entities', { - params: { - query: { - sortDirection, - sortField, - entityTypes: field?.length ? JSON.stringify([field]) : undefined, - kuery, + if (isControlPanelsInitiated) { + return inventoryAPIClient.fetch('GET /internal/inventory/entities', { + params: { + query: { + sortDirection, + sortField, + esQuery: stringifiedEsQuery, + entityTypes: groupValue?.length ? JSON.stringify([groupValue]) : undefined, + }, }, - }, - signal, - }); + signal, + }); + } }, - [field, inventoryAPIClient, kuery, sortDirection, sortField] + [ + groupValue, + inventoryAPIClient, + sortDirection, + sortField, + isControlPanelsInitiated, + stringifiedEsQuery, + ] ); useEffectOnce(() => { @@ -86,7 +94,7 @@ export function GroupedEntitiesGrid({ field }: Props) { ...query, pagination: entityPaginationRt.encode({ ...pagination, - [field]: nextPage, + [groupValue]: nextPage, }), }, }); @@ -103,18 +111,6 @@ export function GroupedEntitiesGrid({ field }: Props) { }); } - function handleTypeFilter(type: string) { - const { pagination: _, ...rest } = query; - inventoryRoute.push('/', { - path: {}, - query: { - ...rest, - // Override the current entity types - entityTypes: [type], - }, - }); - } - return ( ); } diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/index.tsx index b376200495e43..b939f0fa5c423 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/index.tsx @@ -8,20 +8,18 @@ import { EuiSpacer } from '@elastic/eui'; import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; import React from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { InventoryGroupAccordion } from './inventory_group_accordion'; import { useInventoryAbortableAsync } from '../../hooks/use_inventory_abortable_async'; import { useKibana } from '../../hooks/use_kibana'; +import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; +import { InventoryGroupAccordion } from './inventory_group_accordion'; import { InventorySummary } from './inventory_summary'; -import { useInventoryParams } from '../../hooks/use_inventory_params'; -import { useInventorySearchBarContext } from '../../context/inventory_search_bar_context_provider'; export function GroupedInventory() { const { services: { inventoryAPIClient }, } = useKibana(); - const { query } = useInventoryParams('/'); - const { kuery, entityTypes } = query; - const { refreshSubject$ } = useInventorySearchBarContext(); + const { refreshSubject$, isControlPanelsInitiated, stringifiedEsQuery } = + useUnifiedSearchContext(); const { value = { groupBy: ENTITY_TYPE, groups: [], entitiesCount: 0 }, @@ -29,20 +27,19 @@ export function GroupedInventory() { loading, } = useInventoryAbortableAsync( ({ signal }) => { - return inventoryAPIClient.fetch('GET /internal/inventory/entities/group_by/{field}', { - params: { - path: { - field: ENTITY_TYPE, - }, - query: { - kuery, - entityTypes: entityTypes?.length ? JSON.stringify(entityTypes) : undefined, + if (isControlPanelsInitiated) { + return inventoryAPIClient.fetch('GET /internal/inventory/entities/group_by/{field}', { + params: { + path: { + field: ENTITY_TYPE, + }, + query: { esQuery: stringifiedEsQuery }, }, - }, - signal, - }); + signal, + }); + } }, - [entityTypes, inventoryAPIClient, kuery] + [inventoryAPIClient, stringifiedEsQuery, isControlPanelsInitiated] ); useEffectOnce(() => { @@ -58,8 +55,9 @@ export function GroupedInventory() { {value.groups.map((group) => ( ))} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.test.tsx index 2cddbb8e46d79..bf0b7064033f4 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.test.tsx @@ -25,7 +25,13 @@ describe('Grouped Inventory Accordion', () => { }, ], }; - render(); + render( + + ); expect(screen.getByText(props.groups[0]['entity.type'])).toBeInTheDocument(); const container = screen.getByTestId('inventoryPanelBadgeEntitiesCount_entity.type_host'); expect(within(container).getByText('Entities:')).toBeInTheDocument(); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.tsx b/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.tsx index 4c5d34e5a028f..0b4e9a46d4288 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/inventory_group_accordion.tsx @@ -4,12 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useCallback, useState } from 'react'; -import { i18n } from '@kbn/i18n'; -import { css } from '@emotion/react'; import { EuiAccordion, EuiPanel, EuiSpacer, EuiTitle, useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/react'; +import { i18n } from '@kbn/i18n'; +import React, { useCallback, useState } from 'react'; import { GroupedEntitiesGrid } from './grouped_entities_grid'; -import type { EntityGroup } from '../../../common/entities'; import { InventoryPanelBadge } from './inventory_panel_badge'; const ENTITIES_COUNT_BADGE = i18n.translate( @@ -18,18 +17,19 @@ const ENTITIES_COUNT_BADGE = i18n.translate( ); export interface InventoryGroupAccordionProps { - group: EntityGroup; groupBy: string; + groupValue: string; + groupCount: number; isLoading?: boolean; } export function InventoryGroupAccordion({ - group, groupBy, + groupValue, + groupCount, isLoading, }: InventoryGroupAccordionProps) { const { euiTheme } = useEuiTheme(); - const field = group[groupBy]; const [open, setOpen] = useState(false); const onToggle = useCallback(() => { @@ -46,19 +46,19 @@ export function InventoryGroupAccordion({ `} > -

{field}

+

{groupValue}

} buttonElement="div" extraAction={ } buttonProps={{ paddingSize: 'm' }} @@ -78,7 +78,7 @@ export function InventoryGroupAccordion({ hasShadow={false} paddingSize="m" > - + )} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/control_groups.tsx b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/control_groups.tsx new file mode 100644 index 0000000000000..9c263e39562f1 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/control_groups.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 { + ControlGroupRenderer, + ControlGroupRendererApi, + ControlGroupRuntimeState, +} from '@kbn/controls-plugin/public'; +import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; +import { ControlPanels, useControlPanels } from '@kbn/observability-shared-plugin/public'; +import React, { useCallback, useEffect, useRef } from 'react'; +import { skip, Subscription } from 'rxjs'; +import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; + +const controlPanelDefinitions: ControlPanels = { + [ENTITY_TYPE]: { + order: 0, + type: 'optionsListControl', + fieldName: ENTITY_TYPE, + width: 'small', + grow: false, + title: 'Type', + }, +}; + +export function ControlGroups() { + const { + isControlPanelsInitiated, + setIsControlPanelsInitiated, + dataView, + searchState, + onPanelFiltersChange, + } = useUnifiedSearchContext(); + const [controlPanels, setControlPanels] = useControlPanels(controlPanelDefinitions, dataView); + const subscriptions = useRef(new Subscription()); + + const getInitialInput = useCallback( + () => async () => { + const initialInput: Partial = { + chainingSystem: 'HIERARCHICAL', + labelPosition: 'oneLine', + initialChildControlState: controlPanels, + }; + + return { initialState: initialInput }; + }, + [controlPanels] + ); + + const loadCompleteHandler = useCallback( + (controlGroup: ControlGroupRendererApi) => { + if (!controlGroup) return; + + subscriptions.current.add( + controlGroup.filters$.pipe(skip(1)).subscribe((newFilters = []) => { + onPanelFiltersChange(newFilters); + }) + ); + + subscriptions.current.add( + controlGroup.getInput$().subscribe(({ initialChildControlState }) => { + if (!isControlPanelsInitiated) { + setIsControlPanelsInitiated(true); + } + setControlPanels(initialChildControlState); + }) + ); + }, + [isControlPanelsInitiated, onPanelFiltersChange, setControlPanels, setIsControlPanelsInitiated] + ); + + useEffect(() => { + const currentSubscriptions = subscriptions.current; + return () => { + currentSubscriptions.unsubscribe(); + }; + }, []); + + if (!dataView) { + return null; + } + + return ( +
+ +
+ ); +} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/entity_types_controls.tsx b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/entity_types_controls.tsx deleted file mode 100644 index e2d9dba2709f1..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/entity_types_controls.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 { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; -import { css } from '@emotion/react'; -import { i18n } from '@kbn/i18n'; -import React from 'react'; -import { useInventoryAbortableAsync } from '../../hooks/use_inventory_abortable_async'; -import { useInventoryParams } from '../../hooks/use_inventory_params'; -import { useKibana } from '../../hooks/use_kibana'; - -interface Props { - onChange: (entityTypes: string[]) => void; -} - -const toComboBoxOption = (entityType: string): EuiComboBoxOptionOption => ({ - key: entityType, - label: entityType, - 'data-test-subj': `entityTypesFilter${entityType}Option`, -}); - -export function EntityTypesControls({ onChange }: Props) { - const { - query: { entityTypes = [] }, - } = useInventoryParams('/*'); - - const { - services: { inventoryAPIClient }, - } = useKibana(); - - const { value, loading } = useInventoryAbortableAsync( - ({ signal }) => { - return inventoryAPIClient.fetch('GET /internal/inventory/entities/types', { signal }); - }, - [inventoryAPIClient] - ); - - const options = value?.entityTypes.map(toComboBoxOption); - const selectedOptions = entityTypes.map(toComboBoxOption); - - return ( - { - onChange(newOptions.map((option) => option.key).filter((key): key is string => !!key)); - }} - isClearable - /> - ); -} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/index.tsx index 3a22d9bc19a1d..d1ccfd3f358e3 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/search_bar/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/search_bar/index.tsx @@ -4,39 +4,35 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import type { Query } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; -import { SearchBarOwnProps } from '@kbn/unified-search-plugin/public/search_bar'; +import type { SearchBarOwnProps } from '@kbn/unified-search-plugin/public/search_bar'; import deepEqual from 'fast-deep-equal'; import React, { useCallback, useEffect } from 'react'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { Query } from '@kbn/es-query'; -import { useInventorySearchBarContext } from '../../context/inventory_search_bar_context_provider'; -import { useInventoryParams } from '../../hooks/use_inventory_params'; import { useKibana } from '../../hooks/use_kibana'; -import { EntityTypesControls } from './entity_types_controls'; -import { DiscoverButton } from './discover_button'; +import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; import { getKqlFieldsWithFallback } from '../../utils/get_kql_field_names_with_fallback'; +import { ControlGroups } from './control_groups'; +import { DiscoverButton } from './discover_button'; export function SearchBar() { - const { refreshSubject$, searchBarContentSubject$, dataView } = useInventorySearchBarContext(); + const { refreshSubject$, dataView, searchState, onQueryChange } = useUnifiedSearchContext(); + const { services: { unifiedSearch, + telemetry, data: { query: { queryString: queryStringService }, }, - telemetry, }, } = useKibana(); - const { - query: { kuery, entityTypes }, - } = useInventoryParams('/*'); - const { SearchBar: UnifiedSearchBar } = unifiedSearch.ui; const syncSearchBarWithUrl = useCallback(() => { - const query = kuery ? { query: kuery, language: 'kuery' } : undefined; + const query = searchState.query; if (query && !deepEqual(queryStringService.getQuery(), query)) { queryStringService.setQuery(query); } @@ -44,67 +40,36 @@ export function SearchBar() { if (!query) { queryStringService.clearQuery(); } - }, [kuery, queryStringService]); + }, [searchState.query, queryStringService]); useEffect(() => { syncSearchBarWithUrl(); }, [syncSearchBarWithUrl]); const registerSearchSubmittedEvent = useCallback( - ({ - searchQuery, - searchIsUpdate, - searchEntityTypes, - }: { - searchQuery?: Query; - searchEntityTypes?: string[]; - searchIsUpdate?: boolean; - }) => { + ({ searchQuery, searchIsUpdate }: { searchQuery?: Query; searchIsUpdate?: boolean }) => { telemetry.reportEntityInventorySearchQuerySubmitted({ kuery_fields: getKqlFieldsWithFallback(searchQuery?.query as string), - entity_types: searchEntityTypes || [], action: searchIsUpdate ? 'submit' : 'refresh', }); }, [telemetry] ); - const registerEntityTypeFilteredEvent = useCallback( - ({ filterEntityTypes, filterKuery }: { filterEntityTypes: string[]; filterKuery?: string }) => { - telemetry.reportEntityInventoryEntityTypeFiltered({ - entity_types: filterEntityTypes, - kuery_fields: filterKuery ? getKqlFieldsWithFallback(filterKuery) : [], - }); - }, - [telemetry] - ); - - const handleEntityTypesChange = useCallback( - (nextEntityTypes: string[]) => { - searchBarContentSubject$.next({ kuery, entityTypes: nextEntityTypes }); - registerEntityTypeFilteredEvent({ filterEntityTypes: nextEntityTypes, filterKuery: kuery }); - }, - [kuery, registerEntityTypeFilteredEvent, searchBarContentSubject$] - ); - const handleQuerySubmit = useCallback>( - ({ query }, isUpdate) => { - searchBarContentSubject$.next({ - kuery: query?.query as string, - entityTypes, - }); + ({ query = { language: 'kuery', query: '' } }, isUpdate) => { + if (isUpdate) { + onQueryChange(query); + } else { + refreshSubject$.next(); + } registerSearchSubmittedEvent({ searchQuery: query, - searchEntityTypes: entityTypes, searchIsUpdate: isUpdate, }); - - if (!isUpdate) { - refreshSubject$.next(); - } }, - [searchBarContentSubject$, entityTypes, registerSearchSubmittedEvent, refreshSubject$] + [registerSearchSubmittedEvent, onQueryChange, refreshSubject$] ); return ( @@ -113,15 +78,17 @@ export function SearchBar() { } + renderQueryInputAppend={() => } onQuerySubmit={handleQuerySubmit} placeholder={i18n.translate('xpack.inventory.searchBar.placeholder', { defaultMessage: 'Search for your entities by name or its metadata (e.g. entity.type : service)', })} + showDatePicker={false} + showFilterBar + showQueryInput + showQueryMenu /> diff --git a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/unified_inventory.tsx b/x-pack/plugins/observability_solution/inventory/public/components/unified_inventory/index.tsx similarity index 71% rename from x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/unified_inventory.tsx rename to x-pack/plugins/observability_solution/inventory/public/components/unified_inventory/index.tsx index 05f7437a32c4b..1bec6dee990d1 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/grouped_inventory/unified_inventory.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/unified_inventory/index.tsx @@ -5,21 +5,21 @@ * 2.0. */ import { EuiDataGridSorting } from '@elastic/eui'; +import { decodeOrThrow } from '@kbn/io-ts-utils'; import React from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { decodeOrThrow } from '@kbn/io-ts-utils'; import { - type EntityColumnIds, entityPaginationRt, + type EntityColumnIds, type EntityPagination, } from '../../../common/entities'; -import { EntitiesGrid } from '../entities_grid'; import { useInventoryAbortableAsync } from '../../hooks/use_inventory_abortable_async'; import { useInventoryParams } from '../../hooks/use_inventory_params'; import { useInventoryRouter } from '../../hooks/use_inventory_router'; import { useKibana } from '../../hooks/use_kibana'; -import { useInventorySearchBarContext } from '../../context/inventory_search_bar_context_provider'; -import { InventorySummary } from './inventory_summary'; +import { useUnifiedSearchContext } from '../../hooks/use_unified_search_context'; +import { EntitiesGrid } from '../entities_grid'; +import { InventorySummary } from '../grouped_inventory/inventory_summary'; const paginationDecoder = decodeOrThrow(entityPaginationRt); @@ -27,9 +27,11 @@ export function UnifiedInventory() { const { services: { inventoryAPIClient }, } = useKibana(); - const { refreshSubject$ } = useInventorySearchBarContext(); + const { refreshSubject$, isControlPanelsInitiated, stringifiedEsQuery } = + useUnifiedSearchContext(); const { query } = useInventoryParams('/'); - const { sortDirection, sortField, kuery, entityTypes, pagination: paginationQuery } = query; + const { sortDirection, sortField, pagination: paginationQuery } = query; + let pagination: EntityPagination | undefined = {}; const inventoryRoute = useInventoryRouter(); try { @@ -38,9 +40,7 @@ export function UnifiedInventory() { inventoryRoute.push('/', { path: {}, query: { - sortField, - sortDirection, - kuery, + ...query, pagination: undefined, }, }); @@ -55,24 +55,24 @@ export function UnifiedInventory() { refresh, } = useInventoryAbortableAsync( ({ signal }) => { - return inventoryAPIClient.fetch('GET /internal/inventory/entities', { - params: { - query: { - sortDirection, - sortField, - entityTypes: entityTypes?.length ? JSON.stringify(entityTypes) : undefined, - kuery, + if (isControlPanelsInitiated) { + return inventoryAPIClient.fetch('GET /internal/inventory/entities', { + params: { + query: { + sortDirection, + sortField, + esQuery: stringifiedEsQuery, + }, }, - }, - signal, - }); + signal, + }); + } }, - [entityTypes, inventoryAPIClient, kuery, sortDirection, sortField] + [inventoryAPIClient, sortDirection, sortField, isControlPanelsInitiated, stringifiedEsQuery] ); useEffectOnce(() => { const refreshSubscription = refreshSubject$.subscribe(refresh); - return () => refreshSubscription.unsubscribe(); }); @@ -100,19 +100,6 @@ export function UnifiedInventory() { }); } - function handleTypeFilter(type: string) { - const { pagination: _, ...rest } = query; - - inventoryRoute.push('/', { - path: {}, - query: { - ...rest, - // Override the current entity types - entityTypes: [type], - }, - }); - } - return ( <> @@ -124,7 +111,6 @@ export function UnifiedInventory() { onChangePage={handlePageChange} onChangeSort={handleSortChange} pageIndex={pageIndex} - onFilterByType={handleTypeFilter} /> ); diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_discover_redirect.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_discover_redirect.ts index 3c6ba331ec2a0..c29caca7e5b77 100644 --- a/x-pack/plugins/observability_solution/inventory/public/hooks/use_discover_redirect.ts +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_discover_redirect.ts @@ -5,19 +5,16 @@ * 2.0. */ import { - ENTITY_TYPE, ENTITY_DEFINITION_ID, ENTITY_DISPLAY_NAME, ENTITY_LAST_SEEN, + ENTITY_TYPE, } from '@kbn/observability-shared-plugin/common'; import { useCallback } from 'react'; -import { type PhrasesFilter, buildPhrasesFilter } from '@kbn/es-query'; -import type { DataViewField } from '@kbn/data-views-plugin/public'; import type { Entity, EntityColumnIds } from '../../common/entities'; import { unflattenEntity } from '../../common/utils/unflatten_entity'; import { useKibana } from './use_kibana'; -import { useInventoryParams } from './use_inventory_params'; -import { useInventorySearchBarContext } from '../context/inventory_search_bar_context_provider'; +import { useUnifiedSearchContext } from './use_unified_search_context'; const ACTIVE_COLUMNS: EntityColumnIds[] = [ENTITY_DISPLAY_NAME, ENTITY_TYPE, ENTITY_LAST_SEEN]; @@ -25,32 +22,22 @@ export const useDiscoverRedirect = () => { const { services: { share, application, entityManager }, } = useKibana(); - const { - query: { kuery, entityTypes }, - } = useInventoryParams('/*'); - const { dataView } = useInventorySearchBarContext(); + const { + dataView, + searchState: { query, filters, panelFilters }, + } = useUnifiedSearchContext(); const discoverLocator = share.url.locators.get('DISCOVER_APP_LOCATOR'); const getDiscoverEntitiesRedirectUrl = useCallback( (entity?: Entity) => { - const filters: PhrasesFilter[] = []; - - const entityTypeField = (dataView?.getFieldByName(ENTITY_TYPE) ?? - entity?.[ENTITY_TYPE]) as DataViewField; - - if (entityTypes && entityTypeField && dataView) { - const entityTypeFilter = buildPhrasesFilter(entityTypeField, entityTypes, dataView); - filters.push(entityTypeFilter); - } - const entityKqlFilter = entity ? entityManager.entityClient.asKqlFilter(unflattenEntity(entity)) : ''; const kueryWithEntityDefinitionFilters = [ - kuery, + query.query, entityKqlFilter, `${ENTITY_DEFINITION_ID} : builtin*`, ] @@ -62,17 +49,18 @@ export const useDiscoverRedirect = () => { indexPatternId: dataView?.id ?? '', columns: ACTIVE_COLUMNS, query: { query: kueryWithEntityDefinitionFilters, language: 'kuery' }, - filters, + filters: [...filters, ...panelFilters], }) : undefined; }, [ application.capabilities.discover?.show, + dataView?.id, discoverLocator, entityManager.entityClient, - entityTypes, - kuery, - dataView, + filters, + panelFilters, + query.query, ] ); diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_context.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_context.ts new file mode 100644 index 0000000000000..94df3a035f3bb --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_context.ts @@ -0,0 +1,166 @@ +/* + * Copyright 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 { buildEsQuery, type Filter, fromKueryExpression, type Query } from '@kbn/es-query'; +import createContainer from 'constate'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { map, Subject, Subscription, tap } from 'rxjs'; +import { generateFilters } from '@kbn/data-plugin/public'; +import useEffectOnce from 'react-use/lib/useEffectOnce'; +import deepEqual from 'fast-deep-equal'; +import { i18n } from '@kbn/i18n'; +import { useKibanaQuerySettings } from '@kbn/observability-shared-plugin/public'; +import { useAdHocInventoryDataView } from './use_adhoc_inventory_data_view'; +import { useUnifiedSearchUrl } from './use_unified_search_url'; +import { useKibana } from './use_kibana'; + +function useUnifiedSearch() { + const [isControlPanelsInitiated, setIsControlPanelsInitiated] = useState(false); + const { dataView } = useAdHocInventoryDataView(); + const [refreshSubject$] = useState>(new Subject()); + const { searchState, setSearchState } = useUnifiedSearchUrl(); + const kibanaQuerySettings = useKibanaQuerySettings(); + const { + services: { + data: { + query: { filterManager: filterManagerService, queryString: queryStringService }, + }, + notifications, + }, + } = useKibana(); + + useEffectOnce(() => { + if (!deepEqual(filterManagerService.getFilters(), searchState.filters)) { + filterManagerService.setFilters( + searchState.filters.map((item) => ({ + ...item, + meta: { ...item.meta, index: dataView?.id }, + })) + ); + } + + if (!deepEqual(queryStringService.getQuery(), searchState.query)) { + queryStringService.setQuery(searchState.query); + } + }); + + useEffect(() => { + const subscription = new Subscription(); + subscription.add( + filterManagerService + .getUpdates$() + .pipe( + map(() => filterManagerService.getFilters()), + tap((filters) => setSearchState({ type: 'SET_FILTERS', filters })) + ) + .subscribe() + ); + + subscription.add( + queryStringService + .getUpdates$() + .pipe( + map(() => queryStringService.getQuery() as Query), + tap((query) => setSearchState({ type: 'SET_QUERY', query })) + ) + .subscribe() + ); + + return () => { + subscription.unsubscribe(); + }; + }, [filterManagerService, queryStringService, setSearchState]); + + const validateQuery = useCallback( + (query: Query) => { + fromKueryExpression(query.query, kibanaQuerySettings); + }, + [kibanaQuerySettings] + ); + + const onQueryChange = useCallback( + (query: Query) => { + try { + validateQuery(query); + setSearchState({ type: 'SET_QUERY', query }); + } catch (e) { + const err = e as Error; + notifications.toasts.addDanger({ + title: i18n.translate('xpack.inventory.unifiedSearchContext.queryError', { + defaultMessage: 'Error while updating the new query', + }), + text: err.message, + }); + } + }, + [validateQuery, setSearchState, notifications.toasts] + ); + + const onPanelFiltersChange = useCallback( + (panelFilters: Filter[]) => { + setSearchState({ type: 'SET_PANEL_FILTERS', panelFilters }); + }, + [setSearchState] + ); + + const onFiltersChange = useCallback( + (filters: Filter[]) => { + setSearchState({ type: 'SET_FILTERS', filters }); + }, + [setSearchState] + ); + + const addFilter = useCallback( + ({ + fieldName, + operation, + value, + }: { + fieldName: string; + value: string; + operation: '+' | '-'; + }) => { + if (dataView) { + const newFilters = generateFilters( + filterManagerService, + fieldName, + value, + operation, + dataView + ); + setSearchState({ type: 'SET_FILTERS', filters: [...newFilters, ...searchState.filters] }); + } + }, + [dataView, filterManagerService, searchState.filters, setSearchState] + ); + + const stringifiedEsQuery = useMemo(() => { + if (dataView) { + return JSON.stringify( + buildEsQuery(dataView, searchState.query, [ + ...searchState.panelFilters, + ...searchState.filters, + ]) + ); + } + }, [dataView, searchState.panelFilters, searchState.filters, searchState.query]); + + return { + isControlPanelsInitiated, + setIsControlPanelsInitiated, + dataView, + refreshSubject$, + searchState, + addFilter, + stringifiedEsQuery, + onQueryChange, + onPanelFiltersChange, + onFiltersChange, + }; +} + +const UnifiedSearch = createContainer(useUnifiedSearch); +export const [UnifiedSearchProvider, useUnifiedSearchContext] = UnifiedSearch; diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_url.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_url.ts new file mode 100644 index 0000000000000..17cf0ef0d9597 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_unified_search_url.ts @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { FilterStateStore } from '@kbn/es-query'; +import { useUrlState } from '@kbn/observability-shared-plugin/public'; +import { enumeration } from '@kbn/securitysolution-io-ts-types'; +import { fold } from 'fp-ts/lib/Either'; +import { constant, identity } from 'fp-ts/lib/function'; +import { pipe } from 'fp-ts/lib/pipeable'; +import * as t from 'io-ts'; +import { useReducer } from 'react'; +import deepEqual from 'fast-deep-equal'; + +const FilterRT = t.intersection([ + t.type({ + meta: t.partial({ + alias: t.union([t.null, t.string]), + disabled: t.boolean, + negate: t.boolean, + controlledBy: t.string, + group: t.string, + index: t.string, + isMultiIndex: t.boolean, + type: t.string, + key: t.string, + params: t.any, + value: t.any, + }), + }), + t.partial({ + query: t.record(t.string, t.any), + $state: t.type({ + store: enumeration('FilterStateStore', FilterStateStore), + }), + }), +]); +const FiltersRT = t.array(FilterRT); + +const QueryStateRT = t.type({ + language: t.string, + query: t.union([t.string, t.record(t.string, t.any)]), +}); + +const SearchStateRT = t.type({ + panelFilters: FiltersRT, + filters: FiltersRT, + query: QueryStateRT, +}); + +const encodeUrlState = SearchStateRT.encode; +const decodeUrlState = (value: unknown) => { + return pipe(SearchStateRT.decode(value), fold(constant(undefined), identity)); +}; + +type SearchState = t.TypeOf; + +const INITIAL_VALUE: SearchState = { + query: { language: 'kuery', query: '' }, + panelFilters: [], + filters: [], +}; + +export type StateAction = + | { type: 'SET_FILTERS'; filters: SearchState['filters'] } + | { type: 'SET_QUERY'; query: SearchState['query'] } + | { type: 'SET_PANEL_FILTERS'; panelFilters: SearchState['panelFilters'] }; + +const reducer = (state: SearchState, action: StateAction): SearchState => { + switch (action.type) { + case 'SET_FILTERS': + return { ...state, filters: action.filters }; + case 'SET_QUERY': + return { ...state, query: action.query }; + case 'SET_PANEL_FILTERS': + return { ...state, panelFilters: action.panelFilters }; + default: + return state; + } +}; + +export function useUnifiedSearchUrl() { + const [urlState, setUrlState] = useUrlState({ + defaultState: INITIAL_VALUE, + decodeUrlState, + encodeUrlState, + urlStateKey: '_a', + writeDefaultState: true, + }); + + const [searchState, setSearchState] = useReducer(reducer, urlState); + + if (!deepEqual(searchState, urlState)) { + setUrlState(searchState); + } + + return { searchState, setSearchState }; +} diff --git a/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx b/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx index 03f8b6475175a..f34df1a3c8b32 100644 --- a/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx @@ -4,36 +4,12 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useEffect } from 'react'; -import { useInventoryParams } from '../../hooks/use_inventory_params'; -import { useInventorySearchBarContext } from '../../context/inventory_search_bar_context_provider'; -import { useInventoryRouter } from '../../hooks/use_inventory_router'; -import { UnifiedInventory } from '../../components/grouped_inventory/unified_inventory'; +import React from 'react'; import { GroupedInventory } from '../../components/grouped_inventory'; +import { UnifiedInventory } from '../../components/unified_inventory'; +import { useInventoryParams } from '../../hooks/use_inventory_params'; export function InventoryPage() { - const { searchBarContentSubject$ } = useInventorySearchBarContext(); - const inventoryRoute = useInventoryRouter(); const { query } = useInventoryParams('/'); - - useEffect(() => { - const searchBarContentSubscription = searchBarContentSubject$.subscribe( - ({ ...queryParams }) => { - const { pagination: _, ...rest } = query; - - inventoryRoute.push('/', { - path: {}, - query: { ...rest, ...queryParams }, - }); - } - ); - return () => { - searchBarContentSubscription.unsubscribe(); - }; - // If query has updated, the inventoryRoute state is also updated - // as well, so we only need to track changes on query. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [query, searchBarContentSubject$]); - return query.view === 'unified' ? : ; } diff --git a/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx b/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx index 36a15c5ae542c..bf5f8324aab25 100644 --- a/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx @@ -9,12 +9,7 @@ import * as t from 'io-ts'; import React from 'react'; import { InventoryPageTemplate } from '../components/inventory_page_template'; import { InventoryPage } from '../pages/inventory_page'; -import { - defaultEntitySortField, - entityTypesRt, - entityColumnIdsRt, - entityViewRt, -} from '../../common/entities'; +import { defaultEntitySortField, entityColumnIdsRt, entityViewRt } from '../../common/entities'; /** * The array of route definitions to be used when the application @@ -34,10 +29,10 @@ const inventoryRoutes = { sortDirection: t.union([t.literal('asc'), t.literal('desc')]), }), t.partial({ - entityTypes: entityTypesRt, - kuery: t.string, view: entityViewRt, pagination: t.string, + _a: t.string, + controlPanels: t.string, }), ]), }), diff --git a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts index 54d20ea324b11..c4c238fba5f8f 100644 --- a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts +++ b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_client.ts @@ -14,7 +14,6 @@ import { type EntityInventoryViewedParams, type EntityInventorySearchQuerySubmittedParams, type EntityViewClickedParams, - type EntityInventoryEntityTypeFilteredParams, } from './types'; export class TelemetryClient implements ITelemetryClient { @@ -34,12 +33,6 @@ export class TelemetryClient implements ITelemetryClient { this.analytics.reportEvent(TelemetryEventTypes.ENTITY_INVENTORY_SEARCH_QUERY_SUBMITTED, params); }; - public reportEntityInventoryEntityTypeFiltered = ( - params: EntityInventoryEntityTypeFilteredParams - ) => { - this.analytics.reportEvent(TelemetryEventTypes.ENTITY_INVENTORY_ENTITY_TYPE_FILTERED, params); - }; - public reportEntityViewClicked = (params: EntityViewClickedParams) => { this.analytics.reportEvent(TelemetryEventTypes.ENTITY_VIEW_CLICKED, params); }; diff --git a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_events.ts b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_events.ts index d61a90f7d30ab..ec2623fe2a2cc 100644 --- a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_events.ts +++ b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_events.ts @@ -49,15 +49,6 @@ const searchQuerySubmittedEventType: TelemetryEvent = { }, }, }, - entity_types: { - type: 'array', - items: { - type: 'keyword', - _meta: { - description: 'Entity types used in the search.', - }, - }, - }, action: { type: 'keyword', _meta: { @@ -67,30 +58,6 @@ const searchQuerySubmittedEventType: TelemetryEvent = { }, }; -const entityInventoryEntityTypeFilteredEventType: TelemetryEvent = { - eventType: TelemetryEventTypes.ENTITY_INVENTORY_ENTITY_TYPE_FILTERED, - schema: { - entity_types: { - type: 'array', - items: { - type: 'keyword', - _meta: { - description: 'Entity types used in the filter.', - }, - }, - }, - kuery_fields: { - type: 'array', - items: { - type: 'text', - _meta: { - description: 'Kuery fields used in the filter.', - }, - }, - }, - }, -}; - const entityViewClickedEventType: TelemetryEvent = { eventType: TelemetryEventTypes.ENTITY_VIEW_CLICKED, schema: { @@ -113,6 +80,5 @@ export const inventoryTelemetryEventBasedTypes = [ inventoryAddDataEventType, entityInventoryViewedEventType, searchQuerySubmittedEventType, - entityInventoryEntityTypeFilteredEventType, entityViewClickedEventType, ]; diff --git a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts index 415cf0e7d4406..639b771788f5b 100644 --- a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts +++ b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/telemetry_service.test.ts @@ -13,7 +13,6 @@ import { type EntityViewClickedParams, type EntityInventorySearchQuerySubmittedParams, TelemetryEventTypes, - type EntityInventoryEntityTypeFilteredParams, } from './types'; describe('TelemetryService', () => { @@ -115,7 +114,6 @@ describe('TelemetryService', () => { const params: EntityInventorySearchQuerySubmittedParams = { kuery_fields: ['_index'], action: 'submit', - entity_types: ['container'], }; telemetry.reportEntityInventorySearchQuerySubmitted(params); @@ -128,26 +126,6 @@ describe('TelemetryService', () => { }); }); - describe('#reportEntityInventoryEntityTypeFiltered', () => { - it('should report entity type filtered with properties', async () => { - const setupParams = getSetupParams(); - service.setup(setupParams); - const telemetry = service.start(); - const params: EntityInventoryEntityTypeFilteredParams = { - kuery_fields: ['_index'], - entity_types: ['container'], - }; - - telemetry.reportEntityInventoryEntityTypeFiltered(params); - - expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1); - expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith( - TelemetryEventTypes.ENTITY_INVENTORY_ENTITY_TYPE_FILTERED, - params - ); - }); - }); - describe('#reportEntityViewClicked', () => { it('should report entity view clicked with properties', async () => { const setupParams = getSetupParams(); diff --git a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/types.ts b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/types.ts index 0e52d115d4597..0d56f44c2c2f2 100644 --- a/x-pack/plugins/observability_solution/inventory/public/services/telemetry/types.ts +++ b/x-pack/plugins/observability_solution/inventory/public/services/telemetry/types.ts @@ -27,15 +27,9 @@ export interface EntityInventoryViewedParams { export interface EntityInventorySearchQuerySubmittedParams { kuery_fields: string[]; - entity_types: string[]; action: 'submit' | 'refresh'; } -export interface EntityInventoryEntityTypeFilteredParams { - kuery_fields: string[]; - entity_types: string[]; -} - export interface EntityViewClickedParams { entity_type: string; view_type: 'detail' | 'flyout'; @@ -45,7 +39,6 @@ export type TelemetryEventParams = | InventoryAddDataParams | EntityInventoryViewedParams | EntityInventorySearchQuerySubmittedParams - | EntityInventoryEntityTypeFilteredParams | EntityViewClickedParams; export interface ITelemetryClient { @@ -54,7 +47,6 @@ export interface ITelemetryClient { reportEntityInventorySearchQuerySubmitted( params: EntityInventorySearchQuerySubmittedParams ): void; - reportEntityInventoryEntityTypeFiltered(params: EntityInventoryEntityTypeFilteredParams): void; reportEntityViewClicked(params: EntityViewClickedParams): void; } diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_entity_groups.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_entity_groups.ts index b61f245f1aaf2..8c72e18bc0740 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_entity_groups.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_entity_groups.ts @@ -5,11 +5,9 @@ * 2.0. */ +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import type { ObservabilityElasticsearchClient } from '@kbn/observability-utils/es/client/create_observability_es_client'; -import { kqlQuery } from '@kbn/observability-utils/es/queries/kql_query'; import { esqlResultToPlainObjects } from '@kbn/observability-utils/es/utils/esql_result_to_plain_objects'; -import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; -import { ScalarValue } from '@elastic/elasticsearch/lib/api/types'; import { ENTITIES_LATEST_ALIAS, type EntityGroup, @@ -20,38 +18,23 @@ import { getBuiltinEntityDefinitionIdESQLWhereClause } from './query_helper'; export async function getEntityGroupsBy({ inventoryEsClient, field, - kuery, - entityTypes, + esQuery, }: { inventoryEsClient: ObservabilityElasticsearchClient; field: string; - kuery?: string; - entityTypes?: string[]; + esQuery?: QueryDslQueryContainer; }) { const from = `FROM ${ENTITIES_LATEST_ALIAS}`; const where = [getBuiltinEntityDefinitionIdESQLWhereClause()]; - const params: ScalarValue[] = []; - if (entityTypes) { - where.push(`WHERE ${ENTITY_TYPE} IN (${entityTypes.map(() => '?').join()})`); - params.push(...entityTypes); - } - - // STATS doesn't support parameterisation. const group = `STATS count = COUNT(*) by ${field}`; const sort = `SORT ${field} asc`; - // LIMIT doesn't support parameterisation. const limit = `LIMIT ${MAX_NUMBER_OF_ENTITIES}`; const query = [from, ...where, group, sort, limit].join(' | '); const groups = await inventoryEsClient.esql('get_entities_groups', { query, - filter: { - bool: { - filter: kqlQuery(kuery), - }, - }, - params, + filter: esQuery, }); return esqlResultToPlainObjects(groups); diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts index c95a488ad49dd..402d11720a9da 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts @@ -5,11 +5,10 @@ * 2.0. */ +import type { QueryDslQueryContainer, ScalarValue } from '@elastic/elasticsearch/lib/api/types'; +import { ENTITY_LAST_SEEN, ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; import { type ObservabilityElasticsearchClient } from '@kbn/observability-utils/es/client/create_observability_es_client'; -import { kqlQuery } from '@kbn/observability-utils/es/queries/kql_query'; import { esqlResultToPlainObjects } from '@kbn/observability-utils/es/utils/esql_result_to_plain_objects'; -import { ENTITY_LAST_SEEN, ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; -import type { ScalarValue } from '@elastic/elasticsearch/lib/api/types'; import { ENTITIES_LATEST_ALIAS, MAX_NUMBER_OF_ENTITIES, @@ -22,14 +21,14 @@ export async function getLatestEntities({ inventoryEsClient, sortDirection, sortField, + esQuery, entityTypes, - kuery, }: { inventoryEsClient: ObservabilityElasticsearchClient; sortDirection: 'asc' | 'desc'; sortField: EntityColumnIds; + esQuery?: QueryDslQueryContainer; entityTypes?: string[]; - kuery?: string; }) { // alertsCount doesn't exist in entities index. Ignore it and sort by entity.lastSeenTimestamp by default. const entitiesSortField = sortField === 'alertsCount' ? ENTITY_LAST_SEEN : sortField; @@ -50,11 +49,7 @@ export async function getLatestEntities({ const latestEntitiesEsqlResponse = await inventoryEsClient.esql('get_latest_entities', { query, - filter: { - bool: { - filter: [...kqlQuery(kuery)], - }, - }, + filter: esQuery, params, }); diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities_alerts.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities_alerts.ts index e969f1d537e99..8126c69de6922 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities_alerts.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities_alerts.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { kqlQuery, termQuery } from '@kbn/observability-plugin/server'; -import { ALERT_STATUS, ALERT_STATUS_ACTIVE } from '@kbn/rule-data-utils'; +import { termQuery } from '@kbn/observability-plugin/server'; import { ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; +import { ALERT_STATUS, ALERT_STATUS_ACTIVE } from '@kbn/rule-data-utils'; import { AlertsClient } from '../../lib/create_alerts_client.ts/create_alerts_client'; import { getGroupByTermsAgg } from './get_group_by_terms_agg'; import { IdentityFieldsPerEntityType } from './get_identity_fields_per_entity_type'; @@ -21,11 +21,9 @@ type EntityTypeBucketsAggregation = Record; export async function getLatestEntitiesAlerts({ alertsClient, - kuery, identityFieldsPerEntityType, }: { alertsClient: AlertsClient; - kuery?: string; identityFieldsPerEntityType: IdentityFieldsPerEntityType; }): Promise> { if (identityFieldsPerEntityType.size === 0) { @@ -37,7 +35,7 @@ export async function getLatestEntitiesAlerts({ track_total_hits: false, query: { bool: { - filter: [...termQuery(ALERT_STATUS, ALERT_STATUS_ACTIVE), ...kqlQuery(kuery)], + filter: termQuery(ALERT_STATUS, ALERT_STATUS_ACTIVE), }, }, }; diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts index 88d6cb68ee214..ae99713375b19 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts @@ -47,8 +47,8 @@ export const listLatestEntitiesRoute = createInventoryServerRoute({ sortDirection: t.union([t.literal('asc'), t.literal('desc')]), }), t.partial({ + esQuery: jsonRt.pipe(t.UnknownRecord), entityTypes: jsonRt.pipe(t.array(t.string)), - kuery: t.string, }), ]), }), @@ -69,7 +69,7 @@ export const listLatestEntitiesRoute = createInventoryServerRoute({ plugin: `@kbn/${INVENTORY_APP_ID}-plugin`, }); - const { sortDirection, sortField, entityTypes, kuery } = params.query; + const { sortDirection, sortField, esQuery, entityTypes } = params.query; const [alertsClient, latestEntities] = await Promise.all([ createAlertsClient({ plugins, request }), @@ -77,8 +77,8 @@ export const listLatestEntitiesRoute = createInventoryServerRoute({ inventoryEsClient, sortDirection, sortField, + esQuery, entityTypes, - kuery, }), ]); @@ -87,7 +87,6 @@ export const listLatestEntitiesRoute = createInventoryServerRoute({ const alerts = await getLatestEntitiesAlerts({ identityFieldsPerEntityType, alertsClient, - kuery, }); const joined = joinByKey( @@ -114,8 +113,7 @@ export const groupEntitiesByRoute = createInventoryServerRoute({ t.type({ path: t.type({ field: t.literal(ENTITY_TYPE) }) }), t.partial({ query: t.partial({ - kuery: t.string, - entityTypes: jsonRt.pipe(t.array(t.string)), + esQuery: jsonRt.pipe(t.UnknownRecord), }), }), ]), @@ -131,13 +129,12 @@ export const groupEntitiesByRoute = createInventoryServerRoute({ }); const { field } = params.path; - const { kuery, entityTypes } = params.query ?? {}; + const { esQuery } = params.query ?? {}; const groups = await getEntityGroupsBy({ inventoryEsClient, field, - kuery, - entityTypes, + esQuery, }); const entitiesCount = groups.reduce((acc, group) => acc + group.count, 0); diff --git a/x-pack/plugins/observability_solution/inventory/tsconfig.json b/x-pack/plugins/observability_solution/inventory/tsconfig.json index d41ef612c9574..5cb95e8ac6de5 100644 --- a/x-pack/plugins/observability_solution/inventory/tsconfig.json +++ b/x-pack/plugins/observability_solution/inventory/tsconfig.json @@ -56,6 +56,8 @@ "@kbn/zod", "@kbn/dashboard-plugin", "@kbn/deeplinks-analytics", + "@kbn/controls-plugin", + "@kbn/securitysolution-io-ts-types", "@kbn/react-hooks" ] } diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/log_stream/log_stream.tsx b/x-pack/plugins/observability_solution/logs_shared/public/components/log_stream/log_stream.tsx index a9c45828a7555..f82e9436fe5cd 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/log_stream/log_stream.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/log_stream/log_stream.tsx @@ -16,13 +16,13 @@ import { noop } from 'lodash'; import React, { useCallback, useEffect, useMemo } from 'react'; import usePrevious from 'react-use/lib/usePrevious'; import type { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/public'; +import { useKibanaQuerySettings } from '@kbn/observability-shared-plugin/public'; import { LogEntryCursor } from '../../../common/log_entry'; import { defaultLogViewsStaticConfig, LogViewReference } from '../../../common/log_views'; import { BuiltEsQuery, useLogStream } from '../../containers/logs/log_stream'; import { useLogView } from '../../hooks/use_log_view'; import { LogViewsClient } from '../../services/log_views'; import { LogColumnRenderConfiguration } from '../../utils/log_column_render_configuration'; -import { useKibanaQuerySettings } from '../../utils/use_kibana_query_settings'; import { useLogEntryFlyout } from '../logging/log_entry_flyout'; import { ScrollableLogTextStreamView, VisibleInterval } from '../logging/log_text_stream'; import { LogStreamErrorBoundary } from './log_stream_error_boundary'; diff --git a/x-pack/plugins/observability_solution/logs_shared/public/utils/use_kibana_query_settings.ts b/x-pack/plugins/observability_solution/logs_shared/public/utils/use_kibana_query_settings.ts deleted file mode 100644 index 521cd0142303b..0000000000000 --- a/x-pack/plugins/observability_solution/logs_shared/public/utils/use_kibana_query_settings.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { EsQueryConfig } from '@kbn/es-query'; -import { SerializableRecord } from '@kbn/utility-types'; -import { useMemo } from 'react'; -import { UI_SETTINGS } from '@kbn/data-plugin/public'; -import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; - -export const useKibanaQuerySettings = (): EsQueryConfig => { - const [allowLeadingWildcards] = useUiSetting$(UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS); - const [queryStringOptions] = useUiSetting$(UI_SETTINGS.QUERY_STRING_OPTIONS); - const [dateFormatTZ] = useUiSetting$(UI_SETTINGS.DATEFORMAT_TZ); - const [ignoreFilterIfFieldNotInIndex] = useUiSetting$( - UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX - ); - - return useMemo( - () => ({ - allowLeadingWildcards, - queryStringOptions, - dateFormatTZ, - ignoreFilterIfFieldNotInIndex, - }), - [allowLeadingWildcards, dateFormatTZ, ignoreFilterIfFieldNotInIndex, queryStringOptions] - ); -}; diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_control_panels_url_state.ts b/x-pack/plugins/observability_solution/observability_shared/public/hooks/use_control_panels_url_state.ts similarity index 63% rename from x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_control_panels_url_state.ts rename to x-pack/plugins/observability_solution/observability_shared/public/hooks/use_control_panels_url_state.ts index 19c0580c73f86..0ade125dcf816 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/hooks/use_control_panels_url_state.ts +++ b/x-pack/plugins/observability_solution/observability_shared/public/hooks/use_control_panels_url_state.ts @@ -12,85 +12,49 @@ import { fold } from 'fp-ts/lib/Either'; import { constant, identity } from 'fp-ts/lib/function'; import type { DataView } from '@kbn/data-views-plugin/public'; import { useMemo } from 'react'; -import { useUrlState } from '../../../../hooks/use_url_state'; +import { useUrlState } from './use_url_state'; -const HOST_FILTERS_URL_STATE_KEY = 'controlPanels'; +const CONTROL_PANELS_URL_KEY = 'controlPanels'; -export const availableControlsPanels = { - HOST_OS_NAME: 'host.os.name', - CLOUD_PROVIDER: 'cloud.provider', - SERVICE_NAME: 'service.name', -}; - -const controlPanelConfigs: ControlPanels = { - [availableControlsPanels.HOST_OS_NAME]: { - order: 0, - width: 'medium', - grow: false, - type: 'optionsListControl', - fieldName: availableControlsPanels.HOST_OS_NAME, - title: 'Operating System', - }, - [availableControlsPanels.CLOUD_PROVIDER]: { - order: 1, - width: 'medium', - grow: false, - type: 'optionsListControl', - fieldName: availableControlsPanels.CLOUD_PROVIDER, - title: 'Cloud Provider', - }, - [availableControlsPanels.SERVICE_NAME]: { - order: 2, - width: 'medium', - grow: false, - type: 'optionsListControl', - fieldName: availableControlsPanels.SERVICE_NAME, - title: 'Service Name', - }, -}; +const PanelRT = rt.intersection([ + rt.type({ + order: rt.number, + type: rt.string, + }), + rt.partial({ + width: rt.union([rt.literal('medium'), rt.literal('small'), rt.literal('large')]), + grow: rt.boolean, + dataViewId: rt.string, + fieldName: rt.string, + title: rt.union([rt.string, rt.undefined]), + selectedOptions: rt.array(rt.string), + }), +]); -const availableControlPanelFields = Object.values(availableControlsPanels); +const ControlPanelRT = rt.record(rt.string, PanelRT); +export type ControlPanels = rt.TypeOf; -export const useControlPanels = ( +const getVisibleControlPanels = ( + availableControlPanelFields: string[], dataView: DataView | undefined -): [ControlPanels, (state: ControlPanels) => void] => { - const defaultState = useMemo(() => getVisibleControlPanelsConfig(dataView), [dataView]); - - const [controlPanels, setControlPanels] = useUrlState({ - defaultState, - decodeUrlState, - encodeUrlState, - urlStateKey: HOST_FILTERS_URL_STATE_KEY, - }); - - /** - * Configure the control panels as - * 1. Available fields from the data view - * 2. Existing filters from the URL parameter (not colliding with allowed fields from data view) - * 3. Enhanced with dataView.id - */ - const controlsPanelsWithId = dataView - ? mergeDefaultPanelsWithUrlConfig(dataView, controlPanels) - : ({} as ControlPanels); - - return [controlsPanelsWithId, setControlPanels]; -}; - -/** - * Utils - */ -const getVisibleControlPanels = (dataView: DataView | undefined) => { +) => { return availableControlPanelFields.filter( (panelKey) => dataView?.fields.getByName(panelKey) !== undefined ); }; -const getVisibleControlPanelsConfig = (dataView: DataView | undefined) => { - return getVisibleControlPanels(dataView).reduce((panelsMap, panelKey) => { - const config = controlPanelConfigs[panelKey]; - - return { ...panelsMap, [panelKey]: config }; - }, {} as ControlPanels); +const getVisibleControlPanelsConfig = ( + controlPanelConfigs: ControlPanels, + dataView: DataView | undefined +) => { + return getVisibleControlPanels(Object.keys(controlPanelConfigs), dataView).reduce( + (panelsMap, panelKey) => { + const config = controlPanelConfigs[panelKey]; + + return { ...panelsMap, [panelKey]: config }; + }, + {} as ControlPanels + ); }; const addDataViewIdToControlPanels = (controlPanels: ControlPanels, dataViewId: string = '') => { @@ -115,9 +79,13 @@ const cleanControlPanels = (controlPanels: ControlPanels) => { }, {}); }; -const mergeDefaultPanelsWithUrlConfig = (dataView: DataView, urlPanels: ControlPanels = {}) => { +const mergeDefaultPanelsWithUrlConfig = ( + dataView: DataView, + urlPanels: ControlPanels = {}, + controlPanelConfigs: ControlPanels +) => { // Get default panel configs from existing fields in data view - const visiblePanels = getVisibleControlPanelsConfig(dataView); + const visiblePanels = getVisibleControlPanelsConfig(controlPanelConfigs, dataView); // Get list of panel which can be overridden to avoid merging additional config from url const existingKeys = Object.keys(visiblePanels); @@ -130,25 +98,6 @@ const mergeDefaultPanelsWithUrlConfig = (dataView: DataView, urlPanels: ControlP ); }; -const PanelRT = rt.intersection([ - rt.type({ - order: rt.number, - type: rt.string, - }), - rt.partial({ - width: rt.union([rt.literal('medium'), rt.literal('small'), rt.literal('large')]), - grow: rt.boolean, - dataViewId: rt.string, - fieldName: rt.string, - title: rt.union([rt.string, rt.undefined]), - selectedOptions: rt.array(rt.string), - }), -]); - -const ControlPanelRT = rt.record(rt.string, PanelRT); - -type ControlPanels = rt.TypeOf; - const encodeUrlState = (value: ControlPanels) => { if (value) { // Remove the dataView.id on update to make the control panels portable between data views @@ -163,3 +112,32 @@ const decodeUrlState = (value: unknown) => { return pipe(ControlPanelRT.decode(value), fold(constant({}), identity)); } }; + +export const useControlPanels = ( + controlPanelConfigs: ControlPanels, + dataView: DataView | undefined +): [ControlPanels, (state: ControlPanels) => void] => { + const defaultState = useMemo( + () => getVisibleControlPanelsConfig(controlPanelConfigs, dataView), + [controlPanelConfigs, dataView] + ); + + const [controlPanels, setControlPanels] = useUrlState({ + defaultState, + decodeUrlState, + encodeUrlState, + urlStateKey: CONTROL_PANELS_URL_KEY, + }); + + /** + * Configure the control panels as + * 1. Available fields from the data view + * 2. Existing filters from the URL parameter (not colliding with allowed fields from data view) + * 3. Enhanced with dataView.id + */ + const controlsPanelsWithId = dataView + ? mergeDefaultPanelsWithUrlConfig(dataView, controlPanels, controlPanelConfigs) + : ({} as ControlPanels); + + return [controlsPanelsWithId, setControlPanels]; +}; diff --git a/x-pack/plugins/observability_solution/infra/public/hooks/use_kibana_query_settings.ts b/x-pack/plugins/observability_solution/observability_shared/public/hooks/use_kibana_query_settings.ts similarity index 100% rename from x-pack/plugins/observability_solution/infra/public/hooks/use_kibana_query_settings.ts rename to x-pack/plugins/observability_solution/observability_shared/public/hooks/use_kibana_query_settings.ts diff --git a/x-pack/plugins/observability_solution/infra/public/hooks/use_url_state.ts b/x-pack/plugins/observability_solution/observability_shared/public/hooks/use_url_state.ts similarity index 81% rename from x-pack/plugins/observability_solution/infra/public/hooks/use_url_state.ts rename to x-pack/plugins/observability_solution/observability_shared/public/hooks/use_url_state.ts index a581e6536e487..ac18fbe413005 100644 --- a/x-pack/plugins/observability_solution/infra/public/hooks/use_url_state.ts +++ b/x-pack/plugins/observability_solution/observability_shared/public/hooks/use_url_state.ts @@ -5,12 +5,12 @@ * 2.0. */ -import { parse } from 'query-string'; +import { parse, stringify } from 'query-string'; import { Location } from 'history'; import { useCallback, useEffect, useMemo, useState } from 'react'; -import { decode, RisonValue } from '@kbn/rison'; +import { decode, encode, RisonValue } from '@kbn/rison'; import { useHistory } from 'react-router-dom'; -import { replaceStateKeyInQueryString } from '../../common/url_state_storage_service'; +import { url } from '@kbn/kibana-utils-plugin/common'; export const useUrlState = ({ defaultState, @@ -94,7 +94,7 @@ export const useUrlState = ({ return [state, setState] as [typeof state, typeof setState]; }; -const decodeRisonUrlState = (value: string | undefined | null): RisonValue | undefined => { +export const decodeRisonUrlState = (value: string | undefined | null): RisonValue | undefined => { try { return value ? decode(value) : undefined; } catch (error) { @@ -124,3 +124,19 @@ const replaceQueryStringInLocation = (location: Location, queryString: string): }; } }; + +const encodeRisonUrlState = (state: any) => encode(state); + +const replaceStateKeyInQueryString = + (stateKey: string, urlState: UrlState | undefined) => + (queryString: string) => { + const previousQueryValues = parse(queryString, { sort: false }); + const newValue = + typeof urlState === 'undefined' + ? previousQueryValues + : { + ...previousQueryValues, + [stateKey]: encodeRisonUrlState(urlState), + }; + return stringify(url.encodeQuery(newValue), { sort: false, encode: false }); + }; diff --git a/x-pack/plugins/observability_solution/observability_shared/public/index.ts b/x-pack/plugins/observability_solution/observability_shared/public/index.ts index d732a669e45bd..bc9f2c452cc8c 100644 --- a/x-pack/plugins/observability_solution/observability_shared/public/index.ts +++ b/x-pack/plugins/observability_solution/observability_shared/public/index.ts @@ -104,3 +104,7 @@ export { BottomBarActions } from './components/bottom_bar_actions/bottom_bar_act export { FieldValueSelection, FieldValueSuggestions } from './components'; export { AddDataPanel, type AddDataPanelProps } from './components/add_data_panel'; + +export { useUrlState } from './hooks/use_url_state'; +export { type ControlPanels, useControlPanels } from './hooks/use_control_panels_url_state'; +export { useKibanaQuerySettings } from './hooks/use_kibana_query_settings'; diff --git a/x-pack/plugins/observability_solution/observability_shared/tsconfig.json b/x-pack/plugins/observability_solution/observability_shared/tsconfig.json index f68649c85cea6..f7b8a7ff6c573 100644 --- a/x-pack/plugins/observability_solution/observability_shared/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_shared/tsconfig.json @@ -45,6 +45,7 @@ "@kbn/rule-data-utils", "@kbn/es-query", "@kbn/serverless", + "@kbn/data-views-plugin", ], "exclude": ["target/**/*", ".storybook/**/*.js"] } diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index c2d5da848212a..0cff8e466d319 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -26269,8 +26269,6 @@ "xpack.inventory.entitiesGrid.euiDataGrid.lastSeenTooltip": "Horodatage des dernières données reçues pour l'entité (entity.lastSeenTimestamp)", "xpack.inventory.entitiesGrid.euiDataGrid.typeLabel": "Type", "xpack.inventory.entitiesGrid.euiDataGrid.typeTooltip": "Type d'entité (entity.type)", - "xpack.inventory.entityTypesControls.euiComboBox.accessibleScreenReaderLabel": "Filtre des types d'entités", - "xpack.inventory.entityTypesControls.euiComboBox.placeHolderLabel": "Types", "xpack.inventory.featureRegistry.inventoryFeatureName": "Inventory", "xpack.inventory.home.serviceAlertsTable.tooltip.activeAlertsExplanation": "Alertes actives", "xpack.inventory.inventoryLinkTitle": "Inventory", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index ef3bd55d92ef0..17fb0b2ff933d 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -26240,8 +26240,6 @@ "xpack.inventory.entitiesGrid.euiDataGrid.lastSeenTooltip": "エンティティで最後に受信したデータのタイムスタンプ(entity.lastSeenTimestamp)", "xpack.inventory.entitiesGrid.euiDataGrid.typeLabel": "型", "xpack.inventory.entitiesGrid.euiDataGrid.typeTooltip": "エンティティのタイプ(entity.type)", - "xpack.inventory.entityTypesControls.euiComboBox.accessibleScreenReaderLabel": "エンティティタイプフィルター", - "xpack.inventory.entityTypesControls.euiComboBox.placeHolderLabel": "タイプ", "xpack.inventory.featureRegistry.inventoryFeatureName": "インベントリ", "xpack.inventory.home.serviceAlertsTable.tooltip.activeAlertsExplanation": "アクティブアラート", "xpack.inventory.inventoryLinkTitle": "インベントリ", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 6543250dfb98b..6ea71271a6859 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -25767,8 +25767,6 @@ "xpack.inventory.entitiesGrid.euiDataGrid.lastSeenTooltip": "上次接收的实体数据的时间戳 (entity.lastSeenTimestamp)", "xpack.inventory.entitiesGrid.euiDataGrid.typeLabel": "类型", "xpack.inventory.entitiesGrid.euiDataGrid.typeTooltip": "实体的类型 (entity.type)", - "xpack.inventory.entityTypesControls.euiComboBox.accessibleScreenReaderLabel": "实体类型筛选", - "xpack.inventory.entityTypesControls.euiComboBox.placeHolderLabel": "类型", "xpack.inventory.featureRegistry.inventoryFeatureName": "库存", "xpack.inventory.home.serviceAlertsTable.tooltip.activeAlertsExplanation": "活动告警", "xpack.inventory.inventoryLinkTitle": "库存", From 84d79e1442620328bfa85f0b0caec2ca818f2475 Mon Sep 17 00:00:00 2001 From: "elastic-renovate-prod[bot]" <174716857+elastic-renovate-prod[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:41:15 +0100 Subject: [PATCH 010/105] Update dependency @elastic/elasticsearch to ^8.15.2 (main) (#199705) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: elastic-renovate-prod[bot] <174716857+elastic-renovate-prod[bot]@users.noreply.github.com> Co-authored-by: Alejandro Fernández Haro --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ef0d751ff752f..87905c955d2d8 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "@elastic/datemath": "5.0.3", "@elastic/ebt": "^1.1.1", "@elastic/ecs": "^8.11.1", - "@elastic/elasticsearch": "^8.15.1", + "@elastic/elasticsearch": "^8.15.2", "@elastic/ems-client": "8.5.3", "@elastic/eui": "97.3.1", "@elastic/filesaver": "1.1.2", diff --git a/yarn.lock b/yarn.lock index e5e3c6b0020b7..ca28b48ef37c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1721,10 +1721,10 @@ "@elastic/transport" "^8.3.1" tslib "^2.4.0" -"@elastic/elasticsearch@^8.15.1": - version "8.15.1" - resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-8.15.1.tgz#ca294ba11ed1514bf87d4a2e253b11f6cefd8552" - integrity sha512-L3YzSaxrasMMGtcxnktiUDjS5f177L0zpHsBH+jL0LgPhdMk9xN/VKrAaYzvri86IlV5IbveA0ANV6o/BDUmhQ== +"@elastic/elasticsearch@^8.15.2": + version "8.15.2" + resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-8.15.2.tgz#024e3617b0d1db6425b369a7176d3514598e4c9e" + integrity sha512-DTvjK4bs4WkgdQkXZJx2eVcwKzF1it/PyGT3rl1ReUNIWbkzMEKksiDQK3wY1U3WHT4zTuWQi4GrDOC1w5ej8Q== dependencies: "@elastic/transport" "^8.8.1" tslib "^2.4.0" From 803738fa0c8fea3cdfc4760c7b3dd667637de724 Mon Sep 17 00:00:00 2001 From: Sergi Romeu Date: Tue, 12 Nov 2024 11:41:34 +0100 Subject: [PATCH 011/105] [APM] Migrate `/data_view` to deployment agnostic test (#199296) ## Summary Closes https://github.com/elastic/kibana/issues/198965 Part of https://github.com/elastic/kibana/issues/193245 This PR contains the changes to migrate `data_view` test folder to Deployment-agnostic testing strategy. ### How to test - Serverless ``` node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts --grep="APM" ``` It's recommended to be run against [MKI](https://github.com/crespocarlos/kibana/blob/main/x-pack/test_serverless/README.md#run-tests-on-mki) - Stateful ``` node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts --grep="APM" ``` ## Checks - [x] (OPTIONAL, only if a test has been unskipped) Run flaky test suite - [x] local run for serverless - [x] local run for stateful - [x] MKI run for serverless --- .../apis/observability/apm/data_view/index.ts | 14 + .../apm/data_view/static.spec.ts | 291 ++++++++++++++++++ .../apis/observability/apm/index.ts | 1 + .../tests/data_view/static.spec.ts | 268 ---------------- 4 files changed, 306 insertions(+), 268 deletions(-) create mode 100644 x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/data_view/index.ts create mode 100644 x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/data_view/static.spec.ts delete mode 100644 x-pack/test/apm_api_integration/tests/data_view/static.spec.ts diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/data_view/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/data_view/index.ts new file mode 100644 index 0000000000000..9412ddca7cbcb --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/data_view/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ loadTestFile }: DeploymentAgnosticFtrProviderContext) { + describe('data_view', () => { + loadTestFile(require.resolve('./static.spec.ts')); + }); +} diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/data_view/static.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/data_view/static.spec.ts new file mode 100644 index 0000000000000..2dc71cd599bd1 --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/data_view/static.spec.ts @@ -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 { apm, timerange } from '@kbn/apm-synthtrace-client'; +import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; +import expect from '@kbn/expect'; +import { DataView } from '@kbn/data-views-plugin/common'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import request from 'superagent'; +import { getStaticDataViewId } from '@kbn/apm-data-view'; +import { SupertestWithRoleScope } from '../../../../services/role_scoped_supertest'; +import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; +import { + SupertestReturnType, + ApmApiError, +} from '../../../../../../apm_api_integration/common/apm_api_supertest'; + +export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { + const apmApiClient = getService('apmApi'); + const roleScopedSupertest = getService('roleScopedSupertest'); + const synthtraceService = getService('synthtrace'); + const logger = getService('log'); + const dataViewPattern = + 'traces-apm*,apm-*,traces-*.otel-*,logs-apm*,apm-*,logs-*.otel-*,metrics-apm*,apm-*,metrics-*.otel-*'; + + function createDataViewWithWriteUser({ spaceId }: { spaceId: string }) { + return apmApiClient.writeUser({ + endpoint: 'POST /internal/apm/data_view/static', + spaceId, + }); + } + + function createDataViewWithReadUser({ spaceId }: { spaceId: string }) { + return apmApiClient.readUser({ + endpoint: 'POST /internal/apm/data_view/static', + spaceId, + }); + } + + describe('Data view static', () => { + let supertestEditorWithApiKey: SupertestWithRoleScope; + let supertestEditorWithCookieCredentials: SupertestWithRoleScope; + + before(async () => { + supertestEditorWithApiKey = await roleScopedSupertest.getSupertestWithRoleScope('editor', { + withInternalHeaders: true, + }); + + supertestEditorWithCookieCredentials = await roleScopedSupertest.getSupertestWithRoleScope( + 'editor', + { + useCookieHeader: true, + withInternalHeaders: true, + } + ); + }); + + after(async () => { + await supertestEditorWithApiKey.destroy(); + }); + + function deleteDataView(spaceId: string) { + return supertestEditorWithApiKey.delete( + `/s/${spaceId}/api/saved_objects/index-pattern/${getStaticDataViewId(spaceId)}?force=true` + ); + } + + function getDataView({ spaceId }: { spaceId: string }) { + const spacePrefix = spaceId !== 'default' ? `/s/${spaceId}` : ''; + return supertestEditorWithApiKey.get( + `${spacePrefix}/api/saved_objects/index-pattern/${getStaticDataViewId(spaceId)}` + ); + } + + function getDataViewSuggestions(field: string) { + return supertestEditorWithCookieCredentials + .post(`/internal/kibana/suggestions/values/${dataViewPattern}`) + .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .send({ query: '', field, method: 'terms_agg' }); + } + + describe('no mappings exist', () => { + let response: SupertestReturnType<'POST /internal/apm/data_view/static'>; + before(async () => { + response = await createDataViewWithWriteUser({ spaceId: 'default' }); + }); + + it('does not create data view', async () => { + expect(response.status).to.be(200); + expect(response.body).to.eql({ + created: false, + reason: 'No APM data', + }); + }); + + it('cannot fetch data view', async () => { + const res = await getDataView({ spaceId: 'default' }); + expect(res.status).to.be(404); + expect(res.body.message).to.eql( + 'Saved object [index-pattern/apm_static_data_view_id_default] not found' + ); + }); + }); + + describe('when mappings and APM data exists', () => { + let synthtrace: ApmSynthtraceEsClient; + + before(async () => { + synthtrace = await synthtraceService.createApmSynthtraceEsClient(); + await generateApmData(synthtrace); + }); + + after(async () => { + await synthtrace.clean(); + }); + + afterEach(async () => { + try { + await Promise.all([deleteDataView('default'), deleteDataView('foo')]); + } catch (e) { + logger.error(`Could not delete data views ${e.message}`); + } + }); + + describe('when creating data view with write user', () => { + let response: SupertestReturnType<'POST /internal/apm/data_view/static'>; + + before(async () => { + response = await createDataViewWithWriteUser({ spaceId: 'default' }); + }); + + it('successfully creates the apm data view', async () => { + expect(response.status).to.be(200); + + const dataView = (response.body as { dataView: DataView }).dataView; + + expect(dataView.id).to.be('apm_static_data_view_id_default'); + expect(dataView.name).to.be('APM'); + expect(dataView.title).to.be( + 'traces-apm*,apm-*,traces-*.otel-*,logs-apm*,apm-*,logs-*.otel-*,metrics-apm*,apm-*,metrics-*.otel-*' + ); + }); + }); + + describe('when fetching the data view', () => { + let dataViewResponse: request.Response; + + before(async () => { + await createDataViewWithWriteUser({ spaceId: 'default' }); + dataViewResponse = await getDataView({ spaceId: 'default' }); + }); + + it('return 200', () => { + expect(dataViewResponse.status).to.be(200); + }); + + it('has correct id', () => { + expect(dataViewResponse.body.id).to.be('apm_static_data_view_id_default'); + }); + + it('has correct title', () => { + expect(dataViewResponse.body.attributes.title).to.be(dataViewPattern); + }); + + it('has correct attributes', () => { + expect(dataViewResponse.body.attributes.fieldFormatMap).to.be( + JSON.stringify({ + 'trace.id': { + id: 'url', + params: { + urlTemplate: 'apm/link-to/trace/{{value}}', + labelTemplate: '{{value}}', + }, + }, + 'transaction.id': { + id: 'url', + params: { + urlTemplate: 'apm/link-to/transaction/{{value}}', + labelTemplate: '{{value}}', + }, + }, + 'transaction.duration.us': { + id: 'duration', + params: { + inputFormat: 'microseconds', + outputFormat: 'asMilliseconds', + showSuffix: true, + useShortSuffix: true, + outputPrecision: 2, + includeSpaceWithSuffix: true, + }, + }, + }) + ); + }); + + // this test ensures that the default APM Data View doesn't interfere with suggestions returned in the kuery bar (this has been a problem in the past) + it('can get suggestions for `trace.id`', async () => { + const suggestions = await getDataViewSuggestions('trace.id'); + expect(suggestions.body.length).to.be(10); + }); + }); + + describe('when creating data view via read user', () => { + it('throws an error', async () => { + try { + await createDataViewWithReadUser({ spaceId: 'default' }); + } catch (e) { + const err = e as ApmApiError; + const responseBody = err.res.body; + expect(err.res.status).to.eql(403); + expect(responseBody.statusCode).to.eql(403); + expect(responseBody.error).to.eql('Forbidden'); + expect(responseBody.message).to.eql('Unable to create index-pattern'); + } + }); + }); + + describe('when creating data view twice', () => { + it('returns 200 response with reason, if data view already exists', async () => { + await createDataViewWithWriteUser({ spaceId: 'default' }); + const res = await createDataViewWithWriteUser({ spaceId: 'default' }); + + expect(res.status).to.be(200); + expect(res.body).to.eql({ + created: false, + reason: 'Dataview already exists in the active space and does not need to be updated', + }); + }); + }); + + describe('when creating data view in "default" space', () => { + it('can be retrieved from the "default" space', async () => { + await createDataViewWithWriteUser({ spaceId: 'default' }); + const res = await getDataView({ spaceId: 'default' }); + expect(res.body.id).to.eql('apm_static_data_view_id_default'); + expect(res.body.namespaces).to.eql(['default']); + }); + + it('cannot be retrieved from the "foo" space', async () => { + await createDataViewWithWriteUser({ spaceId: 'default' }); + const res = await getDataView({ spaceId: 'foo' }); + expect(res.body.statusCode).to.be(404); + }); + }); + + describe('when creating data view in "foo" space', () => { + it('can be retrieved from the "foo" space', async () => { + await createDataViewWithWriteUser({ spaceId: 'foo' }); + const res = await getDataView({ spaceId: 'foo' }); + expect(res.body.id).to.eql('apm_static_data_view_id_foo'); + expect(res.body.namespaces).to.eql(['foo']); + }); + + it('cannot be retrieved from the "default" space', async () => { + await createDataViewWithWriteUser({ spaceId: 'foo' }); + const res = await getDataView({ spaceId: 'default' }); + expect(res.body.statusCode).to.be(404); + }); + }); + }); + }); +} + +function generateApmData(synthtrace: ApmSynthtraceEsClient) { + const range = timerange( + new Date('2021-10-01T00:00:00.000Z').getTime(), + new Date('2021-10-01T00:01:00.000Z').getTime() + ); + + const instance = apm + .service({ name: 'my-service', environment: 'production', agentName: 'go' }) + .instance('my-instance'); + + return synthtrace.index([ + range + .interval('1s') + .rate(1) + .generator((timestamp) => + instance + .transaction({ transactionName: 'GET /api' }) + .timestamp(timestamp) + .duration(30) + .success() + ), + ]); +} diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts index f1e8fc381a072..22bf6d8aa7f52 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts @@ -15,6 +15,7 @@ export default function apmApiIntegrationTests({ loadTestFile(require.resolve('./mobile')); loadTestFile(require.resolve('./custom_dashboards')); loadTestFile(require.resolve('./dependencies')); + loadTestFile(require.resolve('./data_view')); loadTestFile(require.resolve('./correlations')); loadTestFile(require.resolve('./entities')); loadTestFile(require.resolve('./cold_start')); diff --git a/x-pack/test/apm_api_integration/tests/data_view/static.spec.ts b/x-pack/test/apm_api_integration/tests/data_view/static.spec.ts deleted file mode 100644 index 2d6d1b230ef6e..0000000000000 --- a/x-pack/test/apm_api_integration/tests/data_view/static.spec.ts +++ /dev/null @@ -1,268 +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 { apm, timerange } from '@kbn/apm-synthtrace-client'; -import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; -import expect from '@kbn/expect'; -import { DataView } from '@kbn/data-views-plugin/common'; -import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; -import request from 'superagent'; -import { getStaticDataViewId } from '@kbn/apm-data-view'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { SupertestReturnType, ApmApiError } from '../../common/apm_api_supertest'; - -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const apmApiClient = getService('apmApiClient'); - const supertest = getService('supertest'); - const synthtrace = getService('apmSynthtraceEsClient'); - const logger = getService('log'); - const dataViewPattern = - 'traces-apm*,apm-*,traces-*.otel-*,logs-apm*,apm-*,logs-*.otel-*,metrics-apm*,apm-*,metrics-*.otel-*'; - - function createDataViewWithWriteUser({ spaceId }: { spaceId: string }) { - return apmApiClient.writeUser({ - endpoint: 'POST /internal/apm/data_view/static', - spaceId, - }); - } - - function createDataViewWithReadUser({ spaceId }: { spaceId: string }) { - return apmApiClient.readUser({ - endpoint: 'POST /internal/apm/data_view/static', - spaceId, - }); - } - - function deleteDataView(spaceId: string) { - return supertest - .delete( - `/s/${spaceId}/api/saved_objects/index-pattern/${getStaticDataViewId(spaceId)}?force=true` - ) - .set('kbn-xsrf', 'foo'); - } - - function getDataView({ spaceId }: { spaceId: string }) { - const spacePrefix = spaceId !== 'default' ? `/s/${spaceId}` : ''; - return supertest.get( - `${spacePrefix}/api/saved_objects/index-pattern/${getStaticDataViewId(spaceId)}` - ); - } - - function getDataViewSuggestions(field: string) { - return supertest - .post(`/internal/kibana/suggestions/values/${dataViewPattern}`) - .set('kbn-xsrf', 'foo') - .set(ELASTIC_HTTP_VERSION_HEADER, '1') - .send({ query: '', field, method: 'terms_agg' }); - } - - registry.when('no mappings exist', { config: 'basic', archives: [] }, () => { - let response: SupertestReturnType<'POST /internal/apm/data_view/static'>; - before(async () => { - response = await createDataViewWithWriteUser({ spaceId: 'default' }); - }); - - it('does not create data view', async () => { - expect(response.status).to.be(200); - expect(response.body).to.eql({ - created: false, - reason: 'No APM data', - }); - }); - - it('cannot fetch data view', async () => { - const res = await getDataView({ spaceId: 'default' }); - expect(res.status).to.be(404); - expect(res.body.message).to.eql( - 'Saved object [index-pattern/apm_static_data_view_id_default] not found' - ); - }); - }); - - // FLAKY: https://github.com/elastic/kibana/issues/177120 - registry.when('mappings and APM data exists', { config: 'basic', archives: [] }, () => { - // eslint-disable-next-line mocha/no-sibling-hooks - before(async () => { - await generateApmData(synthtrace); - }); - - after(async () => { - await synthtrace.clean(); - }); - - afterEach(async () => { - try { - await Promise.all([deleteDataView('default'), deleteDataView('foo')]); - } catch (e) { - logger.error(`Could not delete data views ${e.message}`); - } - }); - - describe('when creating data view with write user', () => { - let response: SupertestReturnType<'POST /internal/apm/data_view/static'>; - - before(async () => { - response = await createDataViewWithWriteUser({ spaceId: 'default' }); - }); - - it('successfully creates the apm data view', async () => { - expect(response.status).to.be(200); - - // @ts-expect-error - const dataView = response.body.dataView as DataView; - - expect(dataView.id).to.be('apm_static_data_view_id_default'); - expect(dataView.name).to.be('APM'); - expect(dataView.title).to.be( - 'traces-apm*,apm-*,traces-*.otel-*,logs-apm*,apm-*,logs-*.otel-*,metrics-apm*,apm-*,metrics-*.otel-*' - ); - }); - }); - - describe('when fetching the data view', () => { - let dataViewResponse: request.Response; - - before(async () => { - await createDataViewWithWriteUser({ spaceId: 'default' }); - dataViewResponse = await getDataView({ spaceId: 'default' }); - }); - - it('return 200', () => { - expect(dataViewResponse.status).to.be(200); - }); - - it('has correct id', () => { - expect(dataViewResponse.body.id).to.be('apm_static_data_view_id_default'); - }); - - it('has correct title', () => { - expect(dataViewResponse.body.attributes.title).to.be(dataViewPattern); - }); - - it('has correct attributes', () => { - expect(dataViewResponse.body.attributes.fieldFormatMap).to.be( - JSON.stringify({ - 'trace.id': { - id: 'url', - params: { - urlTemplate: 'apm/link-to/trace/{{value}}', - labelTemplate: '{{value}}', - }, - }, - 'transaction.id': { - id: 'url', - params: { - urlTemplate: 'apm/link-to/transaction/{{value}}', - labelTemplate: '{{value}}', - }, - }, - 'transaction.duration.us': { - id: 'duration', - params: { - inputFormat: 'microseconds', - outputFormat: 'asMilliseconds', - showSuffix: true, - useShortSuffix: true, - outputPrecision: 2, - includeSpaceWithSuffix: true, - }, - }, - }) - ); - }); - - // this test ensures that the default APM Data View doesn't interfere with suggestions returned in the kuery bar (this has been a problem in the past) - it('can get suggestions for `trace.id`', async () => { - const suggestions = await getDataViewSuggestions('trace.id'); - expect(suggestions.body.length).to.be(10); - }); - }); - - describe('when creating data view via read user', () => { - it('throws an error', async () => { - try { - await createDataViewWithReadUser({ spaceId: 'default' }); - } catch (e) { - const err = e as ApmApiError; - const responseBody = err.res.body; - expect(err.res.status).to.eql(403); - expect(responseBody.statusCode).to.eql(403); - expect(responseBody.error).to.eql('Forbidden'); - expect(responseBody.message).to.eql('Unable to create index-pattern'); - } - }); - }); - - describe('when creating data view twice', () => { - it('returns 200 response with reason, if data view already exists', async () => { - await createDataViewWithWriteUser({ spaceId: 'default' }); - const res = await createDataViewWithWriteUser({ spaceId: 'default' }); - - expect(res.status).to.be(200); - expect(res.body).to.eql({ - created: false, - reason: 'Dataview already exists in the active space and does not need to be updated', - }); - }); - }); - - describe('when creating data view in "default" space', () => { - it('can be retrieved from the "default" space', async () => { - await createDataViewWithWriteUser({ spaceId: 'default' }); - const res = await getDataView({ spaceId: 'default' }); - expect(res.body.id).to.eql('apm_static_data_view_id_default'); - expect(res.body.namespaces).to.eql(['default']); - }); - - it('cannot be retrieved from the "foo" space', async () => { - await createDataViewWithWriteUser({ spaceId: 'default' }); - const res = await getDataView({ spaceId: 'foo' }); - expect(res.body.statusCode).to.be(404); - }); - }); - - describe('when creating data view in "foo" space', () => { - it('can be retrieved from the "foo" space', async () => { - await createDataViewWithWriteUser({ spaceId: 'foo' }); - const res = await getDataView({ spaceId: 'foo' }); - expect(res.body.id).to.eql('apm_static_data_view_id_foo'); - expect(res.body.namespaces).to.eql(['foo']); - }); - - it('cannot be retrieved from the "default" space', async () => { - await createDataViewWithWriteUser({ spaceId: 'foo' }); - const res = await getDataView({ spaceId: 'default' }); - expect(res.body.statusCode).to.be(404); - }); - }); - }); -} - -function generateApmData(synthtrace: ApmSynthtraceEsClient) { - const range = timerange( - new Date('2021-10-01T00:00:00.000Z').getTime(), - new Date('2021-10-01T00:01:00.000Z').getTime() - ); - - const instance = apm - .service({ name: 'my-service', environment: 'production', agentName: 'go' }) - .instance('my-instance'); - - return synthtrace.index([ - range - .interval('1s') - .rate(1) - .generator((timestamp) => - instance - .transaction({ transactionName: 'GET /api' }) - .timestamp(timestamp) - .duration(30) - .success() - ), - ]); -} From 93d7044919fc5e08ddc2fa125407451cc3afb800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Tue, 12 Nov 2024 11:59:52 +0100 Subject: [PATCH 012/105] [Feature Flags] Add APM transaction + better example code (#199671) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../public/components/app.tsx | 62 +++++-------- .../public/components/feature_flags_list.tsx | 91 +++++++++++++++++++ examples/feature_flags_example/tsconfig.json | 1 + packages/core/feature-flags/README.mdx | 2 +- .../src/feature_flags_service.ts | 8 ++ 5 files changed, 122 insertions(+), 42 deletions(-) create mode 100644 examples/feature_flags_example/public/components/feature_flags_list.tsx diff --git a/examples/feature_flags_example/public/components/app.tsx b/examples/feature_flags_example/public/components/app.tsx index 432e7dc348abc..97f850b5dd475 100644 --- a/examples/feature_flags_example/public/components/app.tsx +++ b/examples/feature_flags_example/public/components/app.tsx @@ -8,24 +8,15 @@ */ import React from 'react'; -import { - EuiHorizontalRule, - EuiPageTemplate, - EuiTitle, - EuiText, - EuiLink, - EuiListGroup, - EuiListGroupItem, -} from '@elastic/eui'; +import { EuiHorizontalRule, EuiPageTemplate, EuiTitle, EuiText, EuiLink } from '@elastic/eui'; import type { CoreStart, FeatureFlagsStart } from '@kbn/core/public'; -import useObservable from 'react-use/lib/useObservable'; -import { - FeatureFlagExampleBoolean, - FeatureFlagExampleNumber, - FeatureFlagExampleString, -} from '../../common/feature_flags'; import { PLUGIN_NAME } from '../../common'; +import { + FeatureFlagsFullList, + FeatureFlagsReactiveList, + FeatureFlagsStaticList, +} from './feature_flags_list'; interface FeatureFlagsExampleAppDeps { featureFlags: FeatureFlagsStart; @@ -34,16 +25,6 @@ interface FeatureFlagsExampleAppDeps { } export const FeatureFlagsExampleApp = ({ featureFlags }: FeatureFlagsExampleAppDeps) => { - // Fetching the feature flags synchronously - const bool = featureFlags.getBooleanValue(FeatureFlagExampleBoolean, false); - const str = featureFlags.getStringValue(FeatureFlagExampleString, 'red'); - const num = featureFlags.getNumberValue(FeatureFlagExampleNumber, 1); - - // Use React Hooks to observe feature flags changes - const bool$ = useObservable(featureFlags.getBooleanValue$(FeatureFlagExampleBoolean, false)); - const str$ = useObservable(featureFlags.getStringValue$(FeatureFlagExampleString, 'red')); - const num$ = useObservable(featureFlags.getNumberValue$(FeatureFlagExampleNumber, 1)); - return ( <> @@ -67,22 +48,21 @@ export const FeatureFlagsExampleApp = ({ featureFlags }: FeatureFlagsExampleAppD .

- -

- The feature flags are: - - - -

-
- -

- The observed feature flags are: - - - -

-
+

Rendered separately

+

+ Each list are 2 different components, so only the reactive one is re-rendered when the + feature flag is updated and the static one keeps the value until the next refresh. +

+ + + +

Rendered together

+

+ `useObservable` causes a full re-render of the component, updating the{' '} + statically + evaluated flags as well. +

+
diff --git a/examples/feature_flags_example/public/components/feature_flags_list.tsx b/examples/feature_flags_example/public/components/feature_flags_list.tsx new file mode 100644 index 0000000000000..73d6535295865 --- /dev/null +++ b/examples/feature_flags_example/public/components/feature_flags_list.tsx @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { EuiListGroup, EuiListGroupItem } from '@elastic/eui'; +import React from 'react'; +import type { FeatureFlagsStart } from '@kbn/core-feature-flags-browser'; +import useObservable from 'react-use/lib/useObservable'; +import { + FeatureFlagExampleBoolean, + FeatureFlagExampleNumber, + FeatureFlagExampleString, +} from '../../common/feature_flags'; + +export interface FeatureFlagsListProps { + featureFlags: FeatureFlagsStart; +} + +export const FeatureFlagsStaticList = ({ featureFlags }: FeatureFlagsListProps) => { + // Fetching the feature flags synchronously + const bool = featureFlags.getBooleanValue(FeatureFlagExampleBoolean, false); + const str = featureFlags.getStringValue(FeatureFlagExampleString, 'red'); + const num = featureFlags.getNumberValue(FeatureFlagExampleNumber, 1); + + return ( + +

+ The feature flags are: + + + +

+
+ ); +}; + +export const FeatureFlagsReactiveList = ({ featureFlags }: FeatureFlagsListProps) => { + // Use React Hooks to observe feature flags changes + const bool$ = useObservable(featureFlags.getBooleanValue$(FeatureFlagExampleBoolean, false)); + const str$ = useObservable(featureFlags.getStringValue$(FeatureFlagExampleString, 'red')); + const num$ = useObservable(featureFlags.getNumberValue$(FeatureFlagExampleNumber, 1)); + + return ( + +

+ The observed feature flags are: + + + +

+
+ ); +}; + +export const FeatureFlagsFullList = ({ featureFlags }: FeatureFlagsListProps) => { + // Fetching the feature flags synchronously + const bool = featureFlags.getBooleanValue(FeatureFlagExampleBoolean, false); + const str = featureFlags.getStringValue(FeatureFlagExampleString, 'red'); + const num = featureFlags.getNumberValue(FeatureFlagExampleNumber, 1); + + // Use React Hooks to observe feature flags changes + const bool$ = useObservable(featureFlags.getBooleanValue$(FeatureFlagExampleBoolean, false)); + const str$ = useObservable(featureFlags.getStringValue$(FeatureFlagExampleString, 'red')); + const num$ = useObservable(featureFlags.getNumberValue$(FeatureFlagExampleNumber, 1)); + + return ( + <> + +

+ The feature flags are: + + + +

+
+ +

+ The observed feature flags are: + + + +

+
+ + ); +}; diff --git a/examples/feature_flags_example/tsconfig.json b/examples/feature_flags_example/tsconfig.json index bbd68332f3d37..77eb5d09ca85b 100644 --- a/examples/feature_flags_example/tsconfig.json +++ b/examples/feature_flags_example/tsconfig.json @@ -20,5 +20,6 @@ "@kbn/core-plugins-server", "@kbn/config-schema", "@kbn/developer-examples-plugin", + "@kbn/core-feature-flags-browser", ] } diff --git a/packages/core/feature-flags/README.mdx b/packages/core/feature-flags/README.mdx index 99e10b72aa68c..8a28fdf35932b 100644 --- a/packages/core/feature-flags/README.mdx +++ b/packages/core/feature-flags/README.mdx @@ -15,7 +15,7 @@ The service is always enabled, however, it will return the fallback value if a f Kibana only registers a provider when running on Elastic Cloud Hosted/Serverless. And even in those scenarios, we expect that some customers might have network restrictions that might not allow the flags to evaluate. The fallback value must provide a non-broken experience to users. -:warning: Feature Flags are considered dynamic configuration and cannot be used for settings that require restarting Kibana. +⚠️Feature Flags are considered dynamic configuration and cannot be used for settings that require restarting Kibana. One example of invalid use cases are settings used during the `setup` lifecycle of the plugin, such as settings that define if an HTTP route is registered or not. Instead, you should always register the route, and return `404 - Not found` in the route handler if the feature flag returns a _disabled_ state. diff --git a/packages/core/feature-flags/core-feature-flags-browser-internal/src/feature_flags_service.ts b/packages/core/feature-flags/core-feature-flags-browser-internal/src/feature_flags_service.ts index e282cc52ddd4e..afc32d93aee3c 100644 --- a/packages/core/feature-flags/core-feature-flags-browser-internal/src/feature_flags_service.ts +++ b/packages/core/feature-flags/core-feature-flags-browser-internal/src/feature_flags_service.ts @@ -68,7 +68,15 @@ export class FeatureFlagsService { if (this.isProviderReadyPromise) { throw new Error('A provider has already been set. This API cannot be called twice.'); } + const transaction = apm.startTransaction('set-provider', 'feature-flags'); this.isProviderReadyPromise = OpenFeature.setProviderAndWait(provider); + this.isProviderReadyPromise + .then(() => transaction?.end()) + .catch((err) => { + this.logger.error(err); + apm.captureError(err); + transaction?.end(); + }); }, appendContext: (contextToAppend) => this.appendContext(contextToAppend), }; From fb666aa7653ba2cdc56816ac575475e5bb58e1b4 Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Tue, 12 Nov 2024 12:01:23 +0100 Subject: [PATCH 013/105] [APM] Migrate apm alerts tests to deployment agnostic (#199097) ## Summary Closes [#198959](https://github.com/elastic/kibana/issues/198959) Part of https://github.com/elastic/kibana/issues/193245 This PR contains the changes to migrate `alerts` test folder to Deployment-agnostic testing strategy. It also fixes a bug when filtering alerts by `kibana.alert.rule.producer`. On serverless ,the producer is `observability`, not `apm` ### How to test - Serverless ``` node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts --grep="APM" ``` It's recommended to be run against [MKI](https://github.com/crespocarlos/kibana/blob/main/x-pack/test_serverless/README.md#run-tests-on-mki) - This PR won't pass on MKI while the instance is not created using the `kibana.alert.rule.producer` fix from this PR - Stateful ``` node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts --grep="APM" ``` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine --- .github/CODEOWNERS | 1 + .../get_apm_service_summary/index.ts | 5 +- .../get_service_group_alerts.ts | 9 +- .../get_service_transaction_groups_alerts.ts | 11 +- .../get_services/get_service_alerts.ts | 11 +- .../apm/agent_explorer/agent_explorer.spec.ts | 2 +- .../latest_agent_versions.spec.ts | 2 +- .../apm}/alerts/error_count_threshold.spec.ts | 163 +++-- .../apm}/alerts/generate_data.ts | 0 .../apm/alerts/helpers/alerting_helper.ts | 96 +++ .../apis/observability/apm/alerts/index.ts | 19 + .../alerts/preview_chart_error_count.spec.ts | 478 +++++++------- .../alerts/preview_chart_error_rate.spec.ts | 607 ++++++++++++++++++ ...preview_chart_transaction_duration.spec.ts | 564 ++++++++++++++++ .../apm}/alerts/transaction_duration.spec.ts | 141 ++-- .../alerts/transaction_error_rate.spec.ts | 138 ++-- .../apis/observability/apm/index.ts | 1 + .../services/alerting_api.ts | 136 +++- .../deployment_agnostic/services/apm_api.ts | 2 + .../tests/alerts/anomaly_alert.spec.ts | 8 +- .../alerts/helpers/alerting_api_helper.ts | 145 +---- .../helpers/cleanup_rule_and_alert_state.ts | 5 +- .../helpers/wait_for_active_apm_alerts.ts | 4 +- .../helpers/wait_for_alerts_for_rule.ts | 5 +- .../wait_for_index_connector_results.ts | 2 +- .../alerts/preview_chart_error_rate.spec.ts | 599 ----------------- ...preview_chart_transaction_duration.spec.ts | 556 ---------------- .../service_group_count.spec.ts | 2 +- .../tests/services/service_alerts.spec.ts | 2 +- .../transactions_groups_alerts.spec.ts | 2 +- 30 files changed, 2046 insertions(+), 1670 deletions(-) rename x-pack/test/{apm_api_integration/tests => api_integration/deployment_agnostic/apis/observability/apm}/alerts/error_count_threshold.spec.ts (67%) rename x-pack/test/{apm_api_integration/tests => api_integration/deployment_agnostic/apis/observability/apm}/alerts/generate_data.ts (100%) create mode 100644 x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/helpers/alerting_helper.ts create mode 100644 x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/index.ts rename x-pack/test/{apm_api_integration/tests => api_integration/deployment_agnostic/apis/observability/apm}/alerts/preview_chart_error_count.spec.ts (50%) create mode 100644 x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_error_rate.spec.ts create mode 100644 x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_transaction_duration.spec.ts rename x-pack/test/{apm_api_integration/tests => api_integration/deployment_agnostic/apis/observability/apm}/alerts/transaction_duration.spec.ts (67%) rename x-pack/test/{apm_api_integration/tests => api_integration/deployment_agnostic/apis/observability/apm}/alerts/transaction_error_rate.spec.ts (69%) delete mode 100644 x-pack/test/apm_api_integration/tests/alerts/preview_chart_error_rate.spec.ts delete mode 100644 x-pack/test/apm_api_integration/tests/alerts/preview_chart_transaction_duration.spec.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index abc6749d52ea9..ef265cf7c569a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1190,6 +1190,7 @@ x-pack/test_serverless/**/test_suites/observability/ai_assistant @elastic/obs-ai /x-pack/plugins/observability_solution/infra/server/usage @elastic/obs-ux-infra_services-team /x-pack/plugins/observability_solution/infra/server/utils @elastic/obs-ux-infra_services-team /x-pack/test/api_integration/deployment_agnostic/apis/observability/infra @elastic/obs-ux-logs-team +/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm @elastic/obs-ux-logs-team ## Logs UI code exceptions -> @elastic/obs-ux-logs-team /x-pack/test_serverless/functional/page_objects/svl_oblt_onboarding_stream_log_file.ts @elastic/obs-ux-logs-team diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_apm_service_summary/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_apm_service_summary/index.ts index d28152127648b..5c9d40cc22772 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_apm_service_summary/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_apm_service_summary/index.ts @@ -6,13 +6,14 @@ */ import datemath from '@elastic/datemath'; import { ElasticsearchClient, Logger } from '@kbn/core/server'; -import { rangeQuery, ScopedAnnotationsClient } from '@kbn/observability-plugin/server'; +import { rangeQuery, ScopedAnnotationsClient, termsQuery } from '@kbn/observability-plugin/server'; import { ALERT_RULE_PRODUCER, ALERT_STATUS, ALERT_STATUS_ACTIVE, } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; import * as t from 'io-ts'; +import { observabilityFeatureId } from '@kbn/observability-shared-plugin/common'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { Environment } from '../../../../common/environment_rt'; import { SERVICE_NAME } from '../../../../common/es_fields/apm'; @@ -139,7 +140,7 @@ export async function getApmServiceSummary({ query: { bool: { filter: [ - ...termQuery(ALERT_RULE_PRODUCER, 'apm'), + ...termsQuery(ALERT_RULE_PRODUCER, 'apm', observabilityFeatureId), ...termQuery(ALERT_STATUS, ALERT_STATUS_ACTIVE), ...rangeQuery(start, end), ...termQuery(SERVICE_NAME, serviceName), diff --git a/x-pack/plugins/observability_solution/apm/server/routes/service_groups/get_service_group_alerts.ts b/x-pack/plugins/observability_solution/apm/server/routes/service_groups/get_service_group_alerts.ts index 8516527d82b9a..d934863f37e9c 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/service_groups/get_service_group_alerts.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/service_groups/get_service_group_alerts.ts @@ -5,10 +5,11 @@ * 2.0. */ -import { kqlQuery } from '@kbn/observability-plugin/server'; -import { ALERT_RULE_PRODUCER, ALERT_STATUS } from '@kbn/rule-data-utils'; +import { kqlQuery, termQuery, termsQuery } from '@kbn/observability-plugin/server'; +import { ALERT_RULE_PRODUCER, ALERT_STATUS, ALERT_STATUS_ACTIVE } from '@kbn/rule-data-utils'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import { Logger } from '@kbn/core/server'; +import { observabilityFeatureId } from '@kbn/observability-shared-plugin/common'; import { ApmPluginRequestHandlerContext } from '../typings'; import { SavedServiceGroup } from '../../../common/service_groups'; import { ApmAlertsClient } from '../../lib/helpers/get_apm_alerts_client'; @@ -42,8 +43,8 @@ export async function getServiceGroupAlerts({ query: { bool: { filter: [ - { term: { [ALERT_RULE_PRODUCER]: 'apm' } }, - { term: { [ALERT_STATUS]: 'active' } }, + ...termsQuery(ALERT_RULE_PRODUCER, 'apm', observabilityFeatureId), + ...termQuery(ALERT_STATUS, ALERT_STATUS_ACTIVE), ], }, }, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/services/get_service_transaction_groups_alerts.ts b/x-pack/plugins/observability_solution/apm/server/routes/services/get_service_transaction_groups_alerts.ts index 5bdb47cbb1f50..de9c73a30a186 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/services/get_service_transaction_groups_alerts.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/services/get_service_transaction_groups_alerts.ts @@ -5,13 +5,20 @@ * 2.0. */ -import { kqlQuery, termQuery, rangeQuery, wildcardQuery } from '@kbn/observability-plugin/server'; +import { + kqlQuery, + termQuery, + rangeQuery, + wildcardQuery, + termsQuery, +} from '@kbn/observability-plugin/server'; import { ALERT_RULE_PRODUCER, ALERT_STATUS, ALERT_STATUS_ACTIVE, ALERT_RULE_PARAMETERS, } from '@kbn/rule-data-utils'; +import { observabilityFeatureId } from '@kbn/observability-shared-plugin/common'; import { SERVICE_NAME, TRANSACTION_NAME, TRANSACTION_TYPE } from '../../../common/es_fields/apm'; import { LatencyAggregationType } from '../../../common/latency_aggregation_types'; import { AggregationType } from '../../../common/rules/apm_rule_types'; @@ -59,7 +66,7 @@ export async function getServiceTransactionGroupsAlerts({ query: { bool: { filter: [ - ...termQuery(ALERT_RULE_PRODUCER, 'apm'), + ...termsQuery(ALERT_RULE_PRODUCER, 'apm', observabilityFeatureId), ...termQuery(ALERT_STATUS, ALERT_STATUS_ACTIVE), ...rangeQuery(start, end), ...kqlQuery(kuery), diff --git a/x-pack/plugins/observability_solution/apm/server/routes/services/get_services/get_service_alerts.ts b/x-pack/plugins/observability_solution/apm/server/routes/services/get_services/get_service_alerts.ts index b225f3ab70ef1..01a125f456443 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/services/get_services/get_service_alerts.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/services/get_services/get_service_alerts.ts @@ -5,13 +5,20 @@ * 2.0. */ -import { kqlQuery, termQuery, rangeQuery, wildcardQuery } from '@kbn/observability-plugin/server'; +import { + kqlQuery, + termQuery, + rangeQuery, + wildcardQuery, + termsQuery, +} from '@kbn/observability-plugin/server'; import { ALERT_RULE_PRODUCER, ALERT_STATUS, ALERT_STATUS_ACTIVE, ALERT_UUID, } from '@kbn/rule-data-utils'; +import { observabilityFeatureId } from '@kbn/observability-shared-plugin/common'; import { SERVICE_NAME } from '../../../../common/es_fields/apm'; import { ServiceGroup } from '../../../../common/service_groups'; import { ApmAlertsClient } from '../../../lib/helpers/get_apm_alerts_client'; @@ -51,7 +58,7 @@ export async function getServicesAlerts({ query: { bool: { filter: [ - ...termQuery(ALERT_RULE_PRODUCER, 'apm'), + ...termsQuery(ALERT_RULE_PRODUCER, 'apm', observabilityFeatureId), ...termQuery(ALERT_STATUS, ALERT_STATUS_ACTIVE), ...rangeQuery(start, end), ...kqlQuery(kuery), diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/agent_explorer/agent_explorer.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/agent_explorer/agent_explorer.spec.ts index 95d438ba87cad..28471d2055926 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/agent_explorer/agent_explorer.spec.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/agent_explorer/agent_explorer.spec.ts @@ -27,7 +27,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon APIClientRequestParamsOf<'GET /internal/apm/get_agents_per_service'>['params'] > ) { - return await apmApiClient.readUser({ + return apmApiClient.readUser({ endpoint: 'GET /internal/apm/get_agents_per_service', params: { query: { diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/agent_explorer/latest_agent_versions.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/agent_explorer/latest_agent_versions.spec.ts index acc31a3743da8..aa099ca66d23b 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/agent_explorer/latest_agent_versions.spec.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/agent_explorer/latest_agent_versions.spec.ts @@ -14,7 +14,7 @@ export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderCon const unlistedAgentName = 'unlistedAgent'; async function callApi() { - return await apmApiClient.readUser({ + return apmApiClient.readUser({ endpoint: 'GET /internal/apm/get_latest_agent_versions', }); } diff --git a/x-pack/test/apm_api_integration/tests/alerts/error_count_threshold.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/error_count_threshold.spec.ts similarity index 67% rename from x-pack/test/apm_api_integration/tests/alerts/error_count_threshold.spec.ts rename to x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/error_count_threshold.spec.ts index 8b72afc194e35..16493e8220f68 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/error_count_threshold.spec.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/error_count_threshold.spec.ts @@ -10,29 +10,30 @@ import { errorCountActionVariables } from '@kbn/apm-plugin/server/routes/alerts/ import { apm, timerange } from '@kbn/apm-synthtrace-client'; import expect from '@kbn/expect'; import { omit } from 'lodash'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; +import type { RoleCredentials, SupertestWithRoleScopeType } from '../../../../services'; +import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; import { - createApmRule, fetchServiceInventoryAlertCounts, fetchServiceTabAlertCount, ApmAlertFields, - createIndexConnector, getIndexAction, -} from './helpers/alerting_api_helper'; -import { cleanupRuleAndAlertState } from './helpers/cleanup_rule_and_alert_state'; -import { waitForAlertsForRule } from './helpers/wait_for_alerts_for_rule'; -import { waitForIndexConnectorResults } from './helpers/wait_for_index_connector_results'; -import { waitForActiveRule } from './helpers/wait_for_active_rule'; - -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const supertest = getService('supertest'); - const es = getService('es'); - const logger = getService('log'); - const apmApiClient = getService('apmApiClient'); - const apmSynthtraceEsClient = getService('apmSynthtraceEsClient'); - - registry.when('error count threshold alert', { config: 'basic', archives: [] }, () => { + APM_ACTION_VARIABLE_INDEX, + APM_ALERTS_INDEX, +} from './helpers/alerting_helper'; + +export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { + const roleScopedSupertest = getService('roleScopedSupertest'); + const apmApiClient = getService('apmApi'); + const synthtrace = getService('synthtrace'); + const alertingApi = getService('alertingApi'); + const samlAuth = getService('samlAuth'); + + describe('error count threshold alert', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + let supertestViewerWithCookieCredentials: SupertestWithRoleScopeType; + let roleAuthc: RoleCredentials; + const javaErrorMessage = 'a java error'; const phpErrorMessage = 'a php error'; @@ -50,7 +51,17 @@ export default function ApiTest({ getService }: FtrProviderContext) { ], }; - before(() => { + before(async () => { + supertestViewerWithCookieCredentials = await roleScopedSupertest.getSupertestWithRoleScope( + 'viewer', + { + withInternalHeaders: true, + useCookieHeader: true, + } + ); + + roleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('admin'); + const opbeansJava = apm .service({ name: 'opbeans-java', environment: 'production', agentName: 'java' }) .instance('instance'); @@ -95,13 +106,19 @@ export default function ApiTest({ getService }: FtrProviderContext) { ]; }); + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); + return Promise.all([ apmSynthtraceEsClient.index(events), apmSynthtraceEsClient.index(phpEvents), ]); }); - after(() => apmSynthtraceEsClient.clean()); + after(async () => { + await apmSynthtraceEsClient.clean(); + await supertestViewerWithCookieCredentials.destroy(); + await samlAuth.invalidateM2mApiKeyWithRoleScope(roleAuthc); + }); describe('create rule without kql filter', () => { let ruleId: string; @@ -109,31 +126,58 @@ export default function ApiTest({ getService }: FtrProviderContext) { let actionId: string; before(async () => { - actionId = await createIndexConnector({ supertest, name: 'Transation error count' }); + actionId = await alertingApi.createIndexConnector({ + name: 'Transation error count', + indexName: APM_ACTION_VARIABLE_INDEX, + roleAuthc, + }); + const indexAction = getIndexAction({ actionId, actionVariables: errorCountActionVariables, }); - const createdRule = await createApmRule({ - supertest, + + const createdRule = await alertingApi.createRule({ ruleTypeId: ApmRuleType.ErrorCount, name: 'Apm error count without kql query', + consumer: 'apm', + schedule: { + interval: '1m', + }, + tags: ['apm'], params: { ...ruleParams, }, actions: [indexAction], + roleAuthc, }); ruleId = createdRule.id; - alerts = await waitForAlertsForRule({ es, ruleId, minimumAlertCount: 2 }); + alerts = ( + await alertingApi.waitForDocumentInIndex({ + indexName: APM_ALERTS_INDEX, + ruleId, + docCountTarget: 2, + }) + ).hits.hits.map((hit) => hit._source) as ApmAlertFields[]; }); - after(async () => { - await cleanupRuleAndAlertState({ es, supertest, logger }); - }); + after(() => + alertingApi.cleanUpAlerts({ + roleAuthc, + ruleId, + alertIndexName: APM_ALERTS_INDEX, + connectorIndexName: APM_ACTION_VARIABLE_INDEX, + consumer: 'apm', + }) + ); it('checks if rule is active', async () => { - const ruleStatus = await waitForActiveRule({ ruleId, supertest }); + const ruleStatus = await alertingApi.waitForRuleStatus({ + ruleId, + roleAuthc, + expectedStatus: 'active', + }); expect(ruleStatus).to.be('active'); }); @@ -141,7 +185,18 @@ export default function ApiTest({ getService }: FtrProviderContext) { let results: Array>; before(async () => { - results = await waitForIndexConnectorResults({ es, minCount: 2 }); + await alertingApi.waitForRuleStatus({ + ruleId, + roleAuthc, + expectedStatus: 'active', + }); + + results = ( + await alertingApi.waitForDocumentInIndex({ + indexName: APM_ACTION_VARIABLE_INDEX, + docCountTarget: 2, + }) + ).hits.hits.map((hit) => hit._source) as Array>; }); it('produces a index action document for each service', async () => { @@ -151,6 +206,15 @@ export default function ApiTest({ getService }: FtrProviderContext) { ]); }); + it('checks if rule is active', async () => { + const ruleStatus = await alertingApi.waitForRuleStatus({ + ruleId, + roleAuthc, + expectedStatus: 'active', + }); + expect(ruleStatus).to.be('active'); + }); + it('has the right keys', async () => { const phpEntry = results.find((result) => result.serviceName === 'opbeans-php')!; expect(Object.keys(phpEntry).sort()).to.eql([ @@ -170,7 +234,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { it('has the right values', () => { const phpEntry = results.find((result) => result.serviceName === 'opbeans-php')!; - expect(omit(phpEntry, 'alertDetailsUrl')).to.eql({ + expect(omit(phpEntry, 'alertDetailsUrl', 'viewInAppUrl')).to.eql({ environment: 'production', interval: '1 hr', reason: @@ -181,9 +245,12 @@ export default function ApiTest({ getService }: FtrProviderContext) { errorGroupingName: 'a php error', threshold: '1', triggerValue: '30', - viewInAppUrl: - 'http://mockedPublicBaseUrl/app/apm/services/opbeans-php/errors?environment=production', }); + + const url = new URL(phpEntry.viewInAppUrl); + + expect(url.pathname).to.equal('/app/apm/services/opbeans-php/errors'); + expect(url.searchParams.get('environment')).to.equal('production'); }); }); @@ -255,30 +322,48 @@ export default function ApiTest({ getService }: FtrProviderContext) { let ruleId: string; before(async () => { - const createdRule = await createApmRule({ - supertest, + const createdRule = await alertingApi.createRule({ ruleTypeId: ApmRuleType.ErrorCount, name: 'Apm error count with kql query', + consumer: 'apm', + schedule: { + interval: '1m', + }, + tags: ['apm'], params: { + ...ruleParams, searchConfiguration: { query: { query: 'service.name: opbeans-php', language: 'kuery', }, }, - ...ruleParams, }, actions: [], + roleAuthc, }); + ruleId = createdRule.id; }); - after(async () => { - await cleanupRuleAndAlertState({ es, supertest, logger }); - }); + after(() => + alertingApi.cleanUpAlerts({ + roleAuthc, + ruleId, + alertIndexName: APM_ALERTS_INDEX, + connectorIndexName: APM_ACTION_VARIABLE_INDEX, + consumer: 'apm', + }) + ); it('produces one alert for the opbeans-php service', async () => { - const alerts = await waitForAlertsForRule({ es, ruleId }); + const alerts = ( + await alertingApi.waitForDocumentInIndex({ + indexName: APM_ALERTS_INDEX, + ruleId, + }) + ).hits.hits.map((hit) => hit._source) as ApmAlertFields[]; + expect(alerts[0]['kibana.alert.reason']).to.be( 'Error count is 30 in the last 1 hr for service: opbeans-php, env: production, name: tx-php, error key: 000000000000000000000a php error, error name: a php error. Alert when > 1.' ); diff --git a/x-pack/test/apm_api_integration/tests/alerts/generate_data.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/generate_data.ts similarity index 100% rename from x-pack/test/apm_api_integration/tests/alerts/generate_data.ts rename to x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/generate_data.ts diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/helpers/alerting_helper.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/helpers/alerting_helper.ts new file mode 100644 index 0000000000000..e5dcd4a45ac3b --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/helpers/alerting_helper.ts @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common'; +import { ApmDocumentType } from '@kbn/apm-plugin/common/document_type'; +import { RollupInterval } from '@kbn/apm-plugin/common/rollup'; +import { ObservabilityApmAlert } from '@kbn/alerts-as-data-utils'; +import type { ApmApiClient } from '../../../../../services/apm_api'; + +export const APM_ALERTS_INDEX = '.alerts-observability.apm.alerts-*'; +export const APM_ACTION_VARIABLE_INDEX = 'apm-index-connector-test'; + +function getTimerange() { + return { + start: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), + end: new Date(Date.now() + 5 * 60 * 1000).toISOString(), + }; +} + +export async function fetchServiceInventoryAlertCounts(apmApiClient: ApmApiClient) { + const timerange = getTimerange(); + const serviceInventoryResponse = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/services', + params: { + query: { + ...timerange, + environment: 'ENVIRONMENT_ALL', + kuery: '', + probability: 1, + documentType: ApmDocumentType.ServiceTransactionMetric, + rollupInterval: RollupInterval.SixtyMinutes, + useDurationSummary: true, + }, + }, + }); + + return serviceInventoryResponse.body.items.reduce>((acc, item) => { + return { ...acc, [item.serviceName]: item.alertsCount ?? 0 }; + }, {}); +} + +export async function fetchServiceTabAlertCount({ + apmApiClient, + serviceName, +}: { + apmApiClient: ApmApiClient; + serviceName: string; +}) { + const timerange = getTimerange(); + const alertsCountReponse = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/services/{serviceName}/alerts_count', + params: { + path: { + serviceName, + }, + query: { + ...timerange, + environment: 'ENVIRONMENT_ALL', + }, + }, + }); + + return alertsCountReponse.body.alertsCount; +} + +export function getIndexAction({ + actionId, + actionVariables, +}: { + actionId: string; + actionVariables: Array<{ name: string }>; +}) { + return { + group: 'threshold_met', + id: actionId, + params: { + documents: [ + actionVariables.reduce>((acc, actionVariable) => { + acc[actionVariable.name] = `{{context.${actionVariable.name}}}`; + return acc; + }, {}), + ], + }, + frequency: { + notify_when: 'onActionGroupChange', + throttle: null, + summary: false, + }, + }; +} + +export type ApmAlertFields = ParsedTechnicalFields & ObservabilityApmAlert; diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/index.ts new file mode 100644 index 0000000000000..71661e4cbc8bc --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ loadTestFile }: DeploymentAgnosticFtrProviderContext) { + describe('alerts', () => { + loadTestFile(require.resolve('./error_count_threshold.spec.ts')); + loadTestFile(require.resolve('./preview_chart_error_count.spec.ts')); + loadTestFile(require.resolve('./preview_chart_error_rate.spec.ts')); + loadTestFile(require.resolve('./preview_chart_transaction_duration.spec.ts')); + loadTestFile(require.resolve('./transaction_duration.spec.ts')); + loadTestFile(require.resolve('./transaction_error_rate.spec.ts')); + }); +} diff --git a/x-pack/test/apm_api_integration/tests/alerts/preview_chart_error_count.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_error_count.spec.ts similarity index 50% rename from x-pack/test/apm_api_integration/tests/alerts/preview_chart_error_count.spec.ts rename to x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_error_count.spec.ts index f09dbf1ad9184..d6792400fc2bc 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/preview_chart_error_count.spec.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_error_count.spec.ts @@ -5,21 +5,21 @@ * 2.0. */ +import type { PreviewChartResponseItem } from '@kbn/apm-plugin/server/routes/alerts/route'; +import expect from '@kbn/expect'; +import { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; import { + ERROR_GROUP_ID, SERVICE_ENVIRONMENT, SERVICE_NAME, - ERROR_GROUP_ID, -} from '@kbn/apm-plugin/common/es_fields/apm'; -import type { PreviewChartResponseItem } from '@kbn/apm-plugin/server/routes/alerts/route'; -import { getErrorGroupingKey } from '@kbn/apm-synthtrace-client/src/lib/apm/instance'; -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; +} from '@kbn/observability-shared-plugin/common'; +import { generateLongIdWithSeed } from '@kbn/apm-synthtrace-client/src/lib/utils/generate_id'; +import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; import { generateErrorData } from './generate_data'; -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const apmApiClient = getService('apmApiClient'); - const apmSynthtraceEsClient = getService('apmSynthtraceEsClient'); +export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { + const apmApiClient = getService('apmApi'); + const synthtrace = getService('synthtrace'); const start = new Date('2021-01-01T00:00:00.000Z').getTime(); const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; @@ -54,31 +54,9 @@ export default function ApiTest({ getService }: FtrProviderContext) { }, }); - registry.when(`without data loaded`, { config: 'basic', archives: [] }, () => { - it('error_count (without data)', async () => { - const options = getOptions(); - - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', - ...options, - }); - - expect(response.status).to.be(200); - expect(response.body.errorCountChartPreview.series).to.eql([]); - }); - }); - - registry.when.skip(`with data loaded`, { config: 'basic', archives: [] }, () => { - // FLAKY: https://github.com/elastic/kibana/issues/172769 - describe('error_count: with data loaded', () => { - beforeEach(async () => { - await generateErrorData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }); - await generateErrorData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }); - }); - - afterEach(() => apmSynthtraceEsClient.clean()); - - it('with data', async () => { + describe('preview chart error count', () => { + describe(`without data loaded`, () => { + it('error_count (without data)', async () => { const options = getOptions(); const response = await apmApiClient.readUser({ @@ -87,230 +65,254 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); expect(response.status).to.be(200); - expect( - response.body.errorCountChartPreview.series.some((item: PreviewChartResponseItem) => - item.data.some((coordinate) => coordinate.x && coordinate.y) - ) - ).to.equal(true); + expect(response.body.errorCountChartPreview.series).to.eql([]); }); + }); - it('with error grouping key', async () => { - const options = { - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceName: 'synth-go', - errorGroupingKey: `${getErrorGroupingKey('Error 1')}`, - environment: 'ENVIRONMENT_ALL', - interval: '5m', - }, - }, - }; - - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', - ...options, + describe(`with data loaded`, () => { + describe('error_count: with data loaded', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + before(async () => { + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); + await Promise.all([ + generateErrorData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }), + generateErrorData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }), + ]); }); - expect(response.status).to.be(200); - expect( - response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production', y: 250 }]); - }); + after(() => apmSynthtraceEsClient.clean()); - it('with no group by parameter', async () => { - const options = getOptions(); - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', - }); + it('with data', async () => { + const options = getOptions(); - expect(response.status).to.be(200); - expect(response.body.errorCountChartPreview.series.length).to.equal(1); - expect( - response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production', y: 375 }]); - }); + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect( + response.body.errorCountChartPreview.series.some((item: PreviewChartResponseItem) => + item.data.some((coordinate) => coordinate.x && coordinate.y) + ) + ).to.equal(true); + }); - it('with default group by fields', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT], + it('with error grouping key', async () => { + const options = { + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + serviceName: 'synth-go', + errorGroupingKey: `${generateLongIdWithSeed('Error 1')}`, + environment: 'ENVIRONMENT_ALL', + interval: '5m', + }, }, - }, - }; + }; - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect( + response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production', y: 250 }]); }); - expect(response.status).to.be(200); - expect(response.body.errorCountChartPreview.series.length).to.equal(1); - expect( - response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production', y: 375 }]); - }); + it('with no group by parameter', async () => { + const options = getOptions(); + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + }); - it('with group by on error grouping key', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, ERROR_GROUP_ID], + expect(response.status).to.be(200); + expect(response.body.errorCountChartPreview.series.length).to.equal(1); + expect( + response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production', y: 375 }]); + }); + + it('with default group by fields', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT], + }, }, - }, - }; + }; - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', - }); + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + }); - expect(response.status).to.be(200); - expect(response.body.errorCountChartPreview.series.length).to.equal(2); - expect( - response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { - name: `synth-go_production_${getErrorGroupingKey('Error 1')}`, - y: 250, - }, - { - name: `synth-go_production_${getErrorGroupingKey('Error 0')}`, - y: 125, - }, - ]); - }); + expect(response.status).to.be(200); + expect(response.body.errorCountChartPreview.series.length).to.equal(1); + expect( + response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production', y: 375 }]); + }); - it('with group by on error grouping key and filter on error grouping key', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - errorGroupingKey: `${getErrorGroupingKey('Error 0')}`, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, ERROR_GROUP_ID], + it('with group by on error grouping key', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, ERROR_GROUP_ID], + }, }, - }, - }; + }; - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.errorCountChartPreview.series.length).to.equal(2); + expect( + response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { + name: `synth-go_production_${generateLongIdWithSeed('Error 1')}`, + y: 250, + }, + { + name: `synth-go_production_${generateLongIdWithSeed('Error 0')}`, + y: 125, + }, + ]); }); - expect(response.status).to.be(200); - expect(response.body.errorCountChartPreview.series.length).to.equal(1); - expect( - response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { - name: `synth-go_production_${getErrorGroupingKey('Error 0')}`, - y: 125, - }, - ]); - }); + it('with group by on error grouping key and filter on error grouping key', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + errorGroupingKey: `${generateLongIdWithSeed('Error 0')}`, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, ERROR_GROUP_ID], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + }); - it('with empty service name', async () => { - const options = { - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceName: '', - environment: 'ENVIRONMENT_ALL', - interval: '5m', + expect(response.status).to.be(200); + expect(response.body.errorCountChartPreview.series.length).to.equal(1); + expect( + response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { + name: `synth-go_production_${generateLongIdWithSeed('Error 0')}`, + y: 125, }, - }, - }; - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + ]); }); - expect(response.status).to.be(200); - expect( - response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { name: 'synth-go_production', y: 375 }, - { name: 'synth-java_production', y: 375 }, - ]); - }); - - it('with empty service name and group by on error grouping key', async () => { - const options = { - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceName: '', - environment: 'ENVIRONMENT_ALL', - interval: '5m', - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, ERROR_GROUP_ID], + it('with empty service name', async () => { + const options = { + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + serviceName: '', + environment: 'ENVIRONMENT_ALL', + interval: '5m', + }, }, - }, - }; - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + }; + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { name: 'synth-go_production', y: 375 }, + { name: 'synth-java_production', y: 375 }, + ]); }); - expect(response.status).to.be(200); - expect( - response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { - name: `synth-go_production_${getErrorGroupingKey('Error 1')}`, - y: 250, - }, - { - name: `synth-java_production_${getErrorGroupingKey('Error 1')}`, - y: 250, - }, - { - name: `synth-go_production_${getErrorGroupingKey('Error 0')}`, - y: 125, - }, - { - name: `synth-java_production_${getErrorGroupingKey('Error 0')}`, - y: 125, - }, - ]); + it('with empty service name and group by on error grouping key', async () => { + const options = { + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + serviceName: '', + environment: 'ENVIRONMENT_ALL', + interval: '5m', + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, ERROR_GROUP_ID], + }, + }, + }; + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.errorCountChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { + name: `synth-go_production_${generateLongIdWithSeed('Error 1')}`, + y: 250, + }, + { + name: `synth-java_production_${generateLongIdWithSeed('Error 1')}`, + y: 250, + }, + { + name: `synth-go_production_${generateLongIdWithSeed('Error 0')}`, + y: 125, + }, + { + name: `synth-java_production_${generateLongIdWithSeed('Error 0')}`, + y: 125, + }, + ]); + }); }); }); - }); - registry.when.skip( - `with data loaded and using KQL filter`, - { config: 'basic', archives: [] }, - () => { - // FLAKY: https://github.com/elastic/kibana/issues/176975 + describe(`with data loaded and using KQL filter`, () => { describe('error_count: with data loaded and using KQL filter', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; before(async () => { + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); await generateErrorData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }); await generateErrorData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }); }); @@ -340,7 +342,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ...getOptionsWithFilterQuery().params.query, searchConfiguration: JSON.stringify({ query: { - query: `service.name: synth-go and error.grouping_key: ${getErrorGroupingKey( + query: `service.name: synth-go and error.grouping_key: ${generateLongIdWithSeed( 'Error 1' )}`, language: 'kuery', @@ -430,11 +432,11 @@ export default function ApiTest({ getService }: FtrProviderContext) { })) ).to.eql([ { - name: `synth-go_production_${getErrorGroupingKey('Error 1')}`, + name: `synth-go_production_${generateLongIdWithSeed('Error 1')}`, y: 250, }, { - name: `synth-go_production_${getErrorGroupingKey('Error 0')}`, + name: `synth-go_production_${generateLongIdWithSeed('Error 0')}`, y: 125, }, ]); @@ -447,7 +449,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ...getOptionsWithFilterQuery().params.query, searchConfiguration: JSON.stringify({ query: { - query: `service.name: synth-go and error.grouping_key: ${getErrorGroupingKey( + query: `service.name: synth-go and error.grouping_key: ${generateLongIdWithSeed( 'Error 0' )}`, language: 'kuery', @@ -472,7 +474,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { })) ).to.eql([ { - name: `synth-go_production_${getErrorGroupingKey('Error 0')}`, + name: `synth-go_production_${generateLongIdWithSeed('Error 0')}`, y: 125, }, ]); @@ -539,24 +541,24 @@ export default function ApiTest({ getService }: FtrProviderContext) { })) ).to.eql([ { - name: `synth-go_production_${getErrorGroupingKey('Error 1')}`, + name: `synth-go_production_${generateLongIdWithSeed('Error 1')}`, y: 250, }, { - name: `synth-java_production_${getErrorGroupingKey('Error 1')}`, + name: `synth-java_production_${generateLongIdWithSeed('Error 1')}`, y: 250, }, { - name: `synth-go_production_${getErrorGroupingKey('Error 0')}`, + name: `synth-go_production_${generateLongIdWithSeed('Error 0')}`, y: 125, }, { - name: `synth-java_production_${getErrorGroupingKey('Error 0')}`, + name: `synth-java_production_${generateLongIdWithSeed('Error 0')}`, y: 125, }, ]); }); }); - } - ); + }); + }); } diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_error_rate.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_error_rate.spec.ts new file mode 100644 index 0000000000000..3e5c0753fbc1d --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_error_rate.spec.ts @@ -0,0 +1,607 @@ +/* + * Copyright 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 { + SERVICE_ENVIRONMENT, + SERVICE_NAME, + TRANSACTION_NAME, + TRANSACTION_TYPE, +} from '@kbn/observability-shared-plugin/common'; +import type { PreviewChartResponseItem } from '@kbn/apm-plugin/server/routes/alerts/route'; +import expect from '@kbn/expect'; +import { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; +import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; +import { generateErrorData } from './generate_data'; + +export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { + const apmApiClient = getService('apmApi'); + const synthtrace = getService('synthtrace'); + const start = new Date('2021-01-01T00:00:00.000Z').getTime(); + const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; + + const getOptions = () => ({ + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + serviceName: 'synth-go', + transactionType: 'request', + environment: 'ENVIRONMENT_ALL', + interval: '5m', + }, + }, + }); + + const getOptionsWithFilterQuery = () => ({ + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + interval: '5m', + searchConfiguration: JSON.stringify({ + query: { + query: 'service.name: synth-go and transaction.type: request', + language: 'kuery', + }, + }), + serviceName: undefined, + transactionType: undefined, + transactionName: undefined, + environment: 'ENVIRONMENT_ALL', + }, + }, + }); + + describe('preview chart error rate', () => { + describe(`without data loaded`, () => { + it('transaction_error_rate without data', async () => { + const options = getOptions(); + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series).to.eql([]); + }); + }); + + describe(`with data loaded`, () => { + describe('transaction_error_rate: with data loaded', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + before(async () => { + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); + await Promise.all([ + generateErrorData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }), + generateErrorData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }), + ]); + }); + + after(() => apmSynthtraceEsClient.clean()); + + it('with data', async () => { + const options = getOptions(); + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect( + response.body.errorRateChartPreview.series.some((item: PreviewChartResponseItem) => + item.data.some((coordinate) => coordinate.x && coordinate.y) + ) + ).to.equal(true); + }); + + it('with transaction name', async () => { + const options = { + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + serviceName: 'synth-go', + transactionName: 'GET /banana', + transactionType: 'request', + environment: 'ENVIRONMENT_ALL', + interval: '5m', + }, + }, + }; + + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 50 }]); + }); + + it('with nonexistent transaction name', async () => { + const options = { + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + serviceName: 'synth-go', + transactionName: 'foo', + transactionType: 'request', + environment: 'ENVIRONMENT_ALL', + interval: '5m', + }, + }, + }; + + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series).to.eql([]); + }); + + it('with no group by parameter', async () => { + const options = getOptions(); + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series.length).to.equal(1); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 37.5 }]); + }); + + it('with default group by fields', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series.length).to.equal(1); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 37.5 }]); + }); + + it('with group by on transaction name', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series.length).to.equal(2); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { + name: 'synth-go_production_request_GET /banana', + y: 50, + }, + { + name: 'synth-go_production_request_GET /apple', + y: 25, + }, + ]); + }); + + it('with group by on transaction name and filter on transaction name', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + transactionName: 'GET /apple', + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series.length).to.equal(1); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request_GET /apple', y: 25 }]); + }); + + it('with empty service name, transaction name and transaction type', async () => { + const options = { + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + serviceName: '', + transactionName: '', + transactionType: '', + environment: 'ENVIRONMENT_ALL', + interval: '5m', + }, + }, + }; + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { name: 'synth-go_production_request', y: 37.5 }, + { name: 'synth-java_production_request', y: 37.5 }, + ]); + }); + + it('with empty service name, transaction name, transaction type and group by on transaction name', async () => { + const options = { + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + serviceName: '', + transactionName: '', + transactionType: '', + environment: 'ENVIRONMENT_ALL', + interval: '5m', + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { + name: 'synth-go_production_request_GET /banana', + y: 50, + }, + { + name: 'synth-java_production_request_GET /banana', + y: 50, + }, + { + name: 'synth-go_production_request_GET /apple', + y: 25, + }, + { + name: 'synth-java_production_request_GET /apple', + y: 25, + }, + ]); + }); + }); + }); + + describe(`with data loaded and using KQL filter`, () => { + describe('transaction_error_rate: with data loaded and using KQL filter', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + before(async () => { + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); + await Promise.all([ + generateErrorData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }), + generateErrorData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }), + ]); + }); + + after(() => apmSynthtraceEsClient.clean()); + + it('with data', async () => { + const options = getOptionsWithFilterQuery(); + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect( + response.body.errorRateChartPreview.series.some((item: PreviewChartResponseItem) => + item.data.some((coordinate) => coordinate.x && coordinate.y) + ) + ).to.equal(true); + }); + + it('with transaction name in filter query', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: + 'service.name: synth-go and transaction.type: request and transaction.name: GET /banana', + language: 'kuery', + }, + }), + }, + }, + }; + + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 50 }]); + }); + + it('with nonexistent transaction name', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: + 'service.name: synth-go and transaction.type: request and transaction.name: foo', + language: 'kuery', + }, + }), + }, + }, + }; + + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series).to.eql([]); + }); + + it('with no group by parameter', async () => { + const options = getOptionsWithFilterQuery(); + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series.length).to.equal(1); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 37.5 }]); + }); + + it('with default group by fields', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series.length).to.equal(1); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 37.5 }]); + }); + + it('with group by on transaction name', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series.length).to.equal(2); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { + name: 'synth-go_production_request_GET /banana', + y: 50, + }, + { + name: 'synth-go_production_request_GET /apple', + y: 25, + }, + ]); + }); + + it('with group by on transaction name and filter on transaction name', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: + 'service.name: synth-go and transaction.type: request and transaction.name: GET /apple', + language: 'kuery', + }, + }), + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.errorRateChartPreview.series.length).to.equal(1); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request_GET /apple', y: 25 }]); + }); + + it('with empty filter query', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: '', + language: 'kuery', + }, + }), + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { name: 'synth-go_production_request', y: 37.5 }, + { name: 'synth-java_production_request', y: 37.5 }, + ]); + }); + + it('with empty filter query and group by on transaction name', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: '', + language: 'kuery', + }, + }), + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { + name: 'synth-go_production_request_GET /banana', + y: 50, + }, + { + name: 'synth-java_production_request_GET /banana', + y: 50, + }, + { + name: 'synth-go_production_request_GET /apple', + y: 25, + }, + { + name: 'synth-java_production_request_GET /apple', + y: 25, + }, + ]); + }); + }); + }); + }); +} diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_transaction_duration.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_transaction_duration.spec.ts new file mode 100644 index 0000000000000..af7f83c393a68 --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/preview_chart_transaction_duration.spec.ts @@ -0,0 +1,564 @@ +/* + * Copyright 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 { + SERVICE_ENVIRONMENT, + SERVICE_NAME, + TRANSACTION_NAME, + TRANSACTION_TYPE, +} from '@kbn/observability-shared-plugin/common'; +import type { PreviewChartResponseItem } from '@kbn/apm-plugin/server/routes/alerts/route'; +import expect from '@kbn/expect'; +import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; +import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; +import { generateLatencyData } from './generate_data'; + +export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { + const apmApiClient = getService('apmApi'); + const synthtrace = getService('synthtrace'); + const start = new Date('2021-01-01T00:00:00.000Z').getTime(); + const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; + + const getOptions = () => ({ + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + serviceName: 'synth-go', + transactionType: 'request', + environment: 'ENVIRONMENT_ALL', + interval: '5m', + }, + }, + }); + + const getOptionsWithFilterQuery = () => ({ + params: { + query: { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + interval: '5m', + searchConfiguration: JSON.stringify({ + query: { + query: 'service.name: synth-go and transaction.type: request', + language: 'kuery', + }, + }), + serviceName: undefined, + transactionType: undefined, + transactionName: undefined, + environment: 'ENVIRONMENT_ALL', + }, + }, + }); + + describe('preview chart transaction duration', () => { + describe(`without data loaded`, () => { + it('transaction_duration (without data)', async () => { + const options = getOptions(); + + const response = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + ...options, + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series).to.eql([]); + }); + }); + + describe(`with data loaded`, () => { + describe('transaction_duration: with data loaded', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + before(async () => { + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); + + await Promise.all([ + generateLatencyData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }), + generateLatencyData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }), + ]); + }); + + after(() => apmSynthtraceEsClient.clean()); + + it('with data', async () => { + const options = getOptions(); + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.latencyChartPreview.series.some((item: PreviewChartResponseItem) => + item.data.some((coordinate) => coordinate.x && coordinate.y) + ) + ).to.equal(true); + }); + + it('with transaction name', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + transactionName: 'GET /banana', + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 5000 }]); + }); + + it('with nonexistent transaction name', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + transactionName: 'foo', + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series).to.eql([]); + }); + + it('with no group by parameter', async () => { + const options = getOptions(); + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(1); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 7500 }]); + }); + + it('with default group by fields', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(1); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 7500 }]); + }); + + it('with group by on transaction name', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(2); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { name: 'synth-go_production_request_GET /apple', y: 10000 }, + { name: 'synth-go_production_request_GET /banana', y: 5000 }, + ]); + }); + + it('with group by on transaction name and filter on transaction name', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + transactionName: 'GET /apple', + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(1); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request_GET /apple', y: 10000 }]); + }); + + it('with empty service name, transaction name and transaction type', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + serviceName: '', + transactionName: '', + transactionType: '', + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { name: 'synth-go_production_request', y: 7500 }, + { name: 'synth-java_production_request', y: 7500 }, + ]); + }); + + it('with empty service name, transaction name, transaction type and group by on transaction name', async () => { + const options = { + params: { + query: { + ...getOptions().params.query, + serviceName: '', + transactionName: '', + transactionType: '', + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(4); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { name: 'synth-go_production_request_GET /apple', y: 10000 }, + { name: 'synth-java_production_request_GET /apple', y: 10000 }, + { name: 'synth-go_production_request_GET /banana', y: 5000 }, + { name: 'synth-java_production_request_GET /banana', y: 5000 }, + ]); + }); + }); + }); + + describe(`with data loaded and using KQL filter`, () => { + describe('transaction_duration: with data loaded and using KQL filter', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + + before(async () => { + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); + await Promise.all([ + generateLatencyData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }), + generateLatencyData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }), + ]); + }); + + after(() => apmSynthtraceEsClient.clean()); + + it('with data', async () => { + const options = getOptionsWithFilterQuery(); + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.latencyChartPreview.series.some((item: PreviewChartResponseItem) => + item.data.some((coordinate) => coordinate.x && coordinate.y) + ) + ).to.equal(true); + }); + + it('with transaction name in filter query', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: + 'service.name: synth-go and transaction.type: request and transaction.name: GET /banana', + language: 'kuery', + }, + }), + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 5000 }]); + }); + + it('with nonexistent transaction name', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: + 'service.name: synth-go and transaction.type: request and transaction.name: foo', + language: 'kuery', + }, + }), + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series).to.eql([]); + }); + + it('with no group by parameter', async () => { + const options = getOptionsWithFilterQuery(); + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(1); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 7500 }]); + }); + + it('with default group by fields', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(1); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request', y: 7500 }]); + }); + + it('with group by on transaction name', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(2); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { name: 'synth-go_production_request_GET /apple', y: 10000 }, + { name: 'synth-go_production_request_GET /banana', y: 5000 }, + ]); + }); + + it('with group by on transaction name and filter on transaction name', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: + 'service.name: synth-go and transaction.type: request and transaction.name: GET /apple', + language: 'kuery', + }, + }), + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(1); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([{ name: 'synth-go_production_request_GET /apple', y: 10000 }]); + }); + + it('with empty filter query', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: '', + language: 'kuery', + }, + }), + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { name: 'synth-go_production_request', y: 7500 }, + { name: 'synth-java_production_request', y: 7500 }, + ]); + }); + + it('with empty filter query and group by on transaction name', async () => { + const options = { + params: { + query: { + ...getOptionsWithFilterQuery().params.query, + searchConfiguration: JSON.stringify({ + query: { + query: '', + language: 'kuery', + }, + }), + groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], + }, + }, + }; + + const response = await apmApiClient.readUser({ + ...options, + endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', + }); + + expect(response.status).to.be(200); + expect(response.body.latencyChartPreview.series.length).to.equal(4); + expect( + response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ + name: item.name, + y: item.data[0].y, + })) + ).to.eql([ + { name: 'synth-go_production_request_GET /apple', y: 10000 }, + { name: 'synth-java_production_request_GET /apple', y: 10000 }, + { name: 'synth-go_production_request_GET /banana', y: 5000 }, + { name: 'synth-java_production_request_GET /banana', y: 5000 }, + ]); + }); + }); + }); + }); +} diff --git a/x-pack/test/apm_api_integration/tests/alerts/transaction_duration.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/transaction_duration.spec.ts similarity index 67% rename from x-pack/test/apm_api_integration/tests/alerts/transaction_duration.spec.ts rename to x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/transaction_duration.spec.ts index 0d7460ff5be50..0cd3446359557 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/transaction_duration.spec.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/transaction_duration.spec.ts @@ -11,27 +11,24 @@ import { transactionDurationActionVariables } from '@kbn/apm-plugin/server/route import { apm, timerange } from '@kbn/apm-synthtrace-client'; import expect from '@kbn/expect'; import { omit } from 'lodash'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; +import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; +import type { RoleCredentials, SupertestWithRoleScopeType } from '../../../../services'; +import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; import { - createApmRule, fetchServiceInventoryAlertCounts, fetchServiceTabAlertCount, ApmAlertFields, - createIndexConnector, getIndexAction, -} from './helpers/alerting_api_helper'; -import { cleanupRuleAndAlertState } from './helpers/cleanup_rule_and_alert_state'; -import { waitForAlertsForRule } from './helpers/wait_for_alerts_for_rule'; -import { waitForActiveRule } from './helpers/wait_for_active_rule'; -import { waitForIndexConnectorResults } from './helpers/wait_for_index_connector_results'; - -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const supertest = getService('supertest'); - const es = getService('es'); - const logger = getService('log'); - const apmApiClient = getService('apmApiClient'); - const apmSynthtraceEsClient = getService('apmSynthtraceEsClient'); + APM_ACTION_VARIABLE_INDEX, + APM_ALERTS_INDEX, +} from './helpers/alerting_helper'; + +export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { + const roleScopedSupertest = getService('roleScopedSupertest'); + const apmApiClient = getService('apmApi'); + const synthtrace = getService('synthtrace'); + const alertingApi = getService('alertingApi'); + const samlAuth = getService('samlAuth'); const ruleParams = { threshold: 3000, @@ -44,8 +41,22 @@ export default function ApiTest({ getService }: FtrProviderContext) { groupBy: ['service.name', 'service.environment', 'transaction.type', 'transaction.name'], }; - registry.when('transaction duration alert', { config: 'basic', archives: [] }, () => { - before(() => { + describe('transaction duration alert', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + let supertestViewerWithCookieCredentials: SupertestWithRoleScopeType; + let roleAuthc: RoleCredentials; + + before(async () => { + supertestViewerWithCookieCredentials = await roleScopedSupertest.getSupertestWithRoleScope( + 'viewer', + { + withInternalHeaders: true, + useCookieHeader: true, + } + ); + + roleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('admin'); + const opbeansJava = apm .service({ name: 'opbeans-java', environment: 'production', agentName: 'java' }) .instance('instance'); @@ -68,11 +79,15 @@ export default function ApiTest({ getService }: FtrProviderContext) { .success(), ]; }); + + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); return apmSynthtraceEsClient.index(events); }); after(async () => { await apmSynthtraceEsClient.clean(); + await supertestViewerWithCookieCredentials.destroy(); + await samlAuth.invalidateM2mApiKeyWithRoleScope(roleAuthc); }); describe('create rule for opbeans-java without kql filter', () => { @@ -81,31 +96,55 @@ export default function ApiTest({ getService }: FtrProviderContext) { let alerts: ApmAlertFields[]; before(async () => { - actionId = await createIndexConnector({ supertest, name: 'Transation duration' }); + actionId = await alertingApi.createIndexConnector({ + name: 'Transation duration', + indexName: APM_ACTION_VARIABLE_INDEX, + roleAuthc, + }); const indexAction = getIndexAction({ actionId, actionVariables: transactionDurationActionVariables, }); - const createdRule = await createApmRule({ - supertest, + const createdRule = await alertingApi.createRule({ ruleTypeId: ApmRuleType.TransactionDuration, name: 'Apm transaction duration without kql filter', + consumer: 'apm', + schedule: { + interval: '1m', + }, + tags: ['apm'], params: { ...ruleParams, }, actions: [indexAction], + roleAuthc, }); ruleId = createdRule.id; - alerts = await waitForAlertsForRule({ es, ruleId }); + alerts = ( + await alertingApi.waitForDocumentInIndex({ + indexName: APM_ALERTS_INDEX, + ruleId, + }) + ).hits.hits.map((hit) => hit._source) as ApmAlertFields[]; }); - after(async () => { - await cleanupRuleAndAlertState({ es, supertest, logger }); - }); + after(() => + alertingApi.cleanUpAlerts({ + roleAuthc, + ruleId, + alertIndexName: APM_ALERTS_INDEX, + connectorIndexName: APM_ACTION_VARIABLE_INDEX, + consumer: 'apm', + }) + ); it('checks if rule is active', async () => { - const ruleStatus = await waitForActiveRule({ ruleId, supertest }); + const ruleStatus = await alertingApi.waitForRuleStatus({ + ruleId, + roleAuthc, + expectedStatus: 'active', + }); expect(ruleStatus).to.be('active'); }); @@ -113,7 +152,11 @@ export default function ApiTest({ getService }: FtrProviderContext) { let results: Array>; before(async () => { - results = await waitForIndexConnectorResults({ es }); + results = results = ( + await alertingApi.waitForDocumentInIndex({ + indexName: APM_ACTION_VARIABLE_INDEX, + }) + ).hits.hits.map((hit) => hit._source) as Array>; }); it('populates the action connector index with every action variable', async () => { @@ -133,7 +176,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('populates the document with the correct values', async () => { - expect(omit(results[0], 'alertDetailsUrl')).to.eql({ + expect(omit(results[0], 'alertDetailsUrl', 'viewInAppUrl')).to.eql({ environment: 'production', interval: '5 mins', reason: @@ -143,9 +186,13 @@ export default function ApiTest({ getService }: FtrProviderContext) { transactionName: 'tx-java', threshold: '3000', triggerValue: '5,000 ms', - viewInAppUrl: - 'http://mockedPublicBaseUrl/app/apm/services/opbeans-java?transactionType=request&environment=production', }); + + const url = new URL(results[0].viewInAppUrl); + + expect(url.pathname).to.equal('/app/apm/services/opbeans-java'); + expect(url.searchParams.get('transactionType')).to.equal('request'); + expect(url.searchParams.get('environment')).to.equal('production'); }); }); @@ -192,10 +239,14 @@ export default function ApiTest({ getService }: FtrProviderContext) { let alerts: ApmAlertFields[]; beforeEach(async () => { - const createdRule = await createApmRule({ - supertest, + const createdRule = await alertingApi.createRule({ ruleTypeId: ApmRuleType.TransactionDuration, name: 'Apm transaction duration with kql filter', + consumer: 'apm', + schedule: { + interval: '1m', + }, + tags: ['apm'], params: { searchConfiguration: { query: { @@ -207,17 +258,33 @@ export default function ApiTest({ getService }: FtrProviderContext) { ...ruleParams, }, actions: [], + roleAuthc, }); ruleId = createdRule.id; - alerts = await waitForAlertsForRule({ es, ruleId }); + alerts = ( + await alertingApi.waitForDocumentInIndex({ + indexName: APM_ALERTS_INDEX, + ruleId, + }) + ).hits.hits.map((hit) => hit._source) as ApmAlertFields[]; }); - afterEach(async () => { - await cleanupRuleAndAlertState({ es, supertest, logger }); - }); + afterEach(() => + alertingApi.cleanUpAlerts({ + roleAuthc, + ruleId, + alertIndexName: APM_ALERTS_INDEX, + connectorIndexName: APM_ACTION_VARIABLE_INDEX, + consumer: 'apm', + }) + ); it('checks if rule is active', async () => { - const ruleStatus = await waitForActiveRule({ ruleId, supertest }); + const ruleStatus = await alertingApi.waitForRuleStatus({ + ruleId, + roleAuthc, + expectedStatus: 'active', + }); expect(ruleStatus).to.be('active'); }); diff --git a/x-pack/test/apm_api_integration/tests/alerts/transaction_error_rate.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/transaction_error_rate.spec.ts similarity index 69% rename from x-pack/test/apm_api_integration/tests/alerts/transaction_error_rate.spec.ts rename to x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/transaction_error_rate.spec.ts index 509d839ecef6d..e538ff0e6a3ba 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/transaction_error_rate.spec.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/alerts/transaction_error_rate.spec.ts @@ -10,30 +10,41 @@ import { transactionErrorRateActionVariables } from '@kbn/apm-plugin/server/rout import { apm, timerange } from '@kbn/apm-synthtrace-client'; import expect from '@kbn/expect'; import { omit } from 'lodash'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; +import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; +import type { RoleCredentials, SupertestWithRoleScopeType } from '../../../../services'; +import type { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; import { - createApmRule, fetchServiceInventoryAlertCounts, fetchServiceTabAlertCount, ApmAlertFields, getIndexAction, - createIndexConnector, -} from './helpers/alerting_api_helper'; -import { cleanupRuleAndAlertState } from './helpers/cleanup_rule_and_alert_state'; -import { waitForAlertsForRule } from './helpers/wait_for_alerts_for_rule'; -import { waitForActiveRule } from './helpers/wait_for_active_rule'; -import { waitForIndexConnectorResults } from './helpers/wait_for_index_connector_results'; - -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const supertest = getService('supertest'); - const es = getService('es'); - const logger = getService('log'); - const apmApiClient = getService('apmApiClient'); - const apmSynthtraceEsClient = getService('apmSynthtraceEsClient'); - - registry.when('transaction error rate alert', { config: 'basic', archives: [] }, () => { - before(() => { + APM_ACTION_VARIABLE_INDEX, + APM_ALERTS_INDEX, +} from './helpers/alerting_helper'; + +export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { + const roleScopedSupertest = getService('roleScopedSupertest'); + const apmApiClient = getService('apmApi'); + const synthtrace = getService('synthtrace'); + const alertingApi = getService('alertingApi'); + const samlAuth = getService('samlAuth'); + + describe('transaction error rate alert', () => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + let supertestViewerWithCookieCredentials: SupertestWithRoleScopeType; + let roleAuthc: RoleCredentials; + + before(async () => { + supertestViewerWithCookieCredentials = await roleScopedSupertest.getSupertestWithRoleScope( + 'viewer', + { + withInternalHeaders: true, + useCookieHeader: true, + } + ); + + roleAuthc = await samlAuth.createM2mApiKeyWithRoleScope('admin'); + const opbeansJava = apm .service({ name: 'opbeans-java', environment: 'production', agentName: 'java' }) .instance('instance'); @@ -66,11 +77,15 @@ export default function ApiTest({ getService }: FtrProviderContext) { .success(), ]; }); + + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); return apmSynthtraceEsClient.index(events); }); after(async () => { await apmSynthtraceEsClient.clean(); + await supertestViewerWithCookieCredentials.destroy(); + await samlAuth.invalidateM2mApiKeyWithRoleScope(roleAuthc); }); describe('create rule without kql query', () => { @@ -79,16 +94,25 @@ export default function ApiTest({ getService }: FtrProviderContext) { let alerts: ApmAlertFields[]; before(async () => { - actionId = await createIndexConnector({ supertest, name: 'Transation error rate' }); + actionId = await alertingApi.createIndexConnector({ + name: 'Transation error rate', + indexName: APM_ACTION_VARIABLE_INDEX, + roleAuthc, + }); + const indexAction = getIndexAction({ actionId, actionVariables: transactionErrorRateActionVariables, }); - const createdRule = await createApmRule({ - supertest, + const createdRule = await alertingApi.createRule({ ruleTypeId: ApmRuleType.TransactionErrorRate, name: 'Apm transaction error rate without kql query', + consumer: 'apm', + schedule: { + interval: '1m', + }, + tags: ['apm'], params: { threshold: 40, windowSize: 5, @@ -104,17 +128,33 @@ export default function ApiTest({ getService }: FtrProviderContext) { ], }, actions: [indexAction], + roleAuthc, }); ruleId = createdRule.id; - alerts = await waitForAlertsForRule({ es, ruleId }); + alerts = ( + await alertingApi.waitForDocumentInIndex({ + indexName: APM_ALERTS_INDEX, + ruleId, + }) + ).hits.hits.map((hit) => hit._source) as ApmAlertFields[]; }); - after(async () => { - await cleanupRuleAndAlertState({ es, supertest, logger }); - }); + after(() => + alertingApi.cleanUpAlerts({ + roleAuthc, + ruleId, + alertIndexName: APM_ALERTS_INDEX, + connectorIndexName: APM_ACTION_VARIABLE_INDEX, + consumer: 'apm', + }) + ); it('checks if rule is active', async () => { - const ruleStatus = await waitForActiveRule({ ruleId, supertest }); + const ruleStatus = await alertingApi.waitForRuleStatus({ + ruleId, + roleAuthc, + expectedStatus: 'active', + }); expect(ruleStatus).to.be('active'); }); @@ -122,7 +162,11 @@ export default function ApiTest({ getService }: FtrProviderContext) { let results: Array>; before(async () => { - results = await waitForIndexConnectorResults({ es }); + results = results = ( + await alertingApi.waitForDocumentInIndex({ + indexName: APM_ACTION_VARIABLE_INDEX, + }) + ).hits.hits.map((hit) => hit._source) as Array>; }); it('has the right keys', async () => { @@ -142,7 +186,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('has the right values', () => { - expect(omit(results[0], 'alertDetailsUrl')).to.eql({ + expect(omit(results[0], 'alertDetailsUrl', 'viewInAppUrl')).to.eql({ environment: 'production', interval: '5 mins', reason: @@ -152,9 +196,13 @@ export default function ApiTest({ getService }: FtrProviderContext) { threshold: '40', transactionType: 'request', triggerValue: '50', - viewInAppUrl: - 'http://mockedPublicBaseUrl/app/apm/services/opbeans-java?transactionType=request&environment=production', }); + + const url = new URL(results[0].viewInAppUrl); + + expect(url.pathname).to.equal('/app/apm/services/opbeans-java'); + expect(url.searchParams.get('transactionType')).to.equal('request'); + expect(url.searchParams.get('environment')).to.equal('production'); }); }); @@ -201,10 +249,14 @@ export default function ApiTest({ getService }: FtrProviderContext) { let alerts: ApmAlertFields[]; beforeEach(async () => { - const createdRule = await createApmRule({ - supertest, + const createdRule = await alertingApi.createRule({ ruleTypeId: ApmRuleType.TransactionErrorRate, name: 'Apm transaction error rate without kql query', + consumer: 'apm', + schedule: { + interval: '1m', + }, + tags: ['apm'], params: { threshold: 40, windowSize: 5, @@ -227,14 +279,26 @@ export default function ApiTest({ getService }: FtrProviderContext) { ], }, actions: [], + roleAuthc, }); ruleId = createdRule.id; - alerts = await waitForAlertsForRule({ es, ruleId }); + alerts = ( + await alertingApi.waitForDocumentInIndex({ + indexName: APM_ALERTS_INDEX, + ruleId, + }) + ).hits.hits.map((hit) => hit._source) as ApmAlertFields[]; }); - afterEach(async () => { - await cleanupRuleAndAlertState({ es, supertest, logger }); - }); + afterEach(() => + alertingApi.cleanUpAlerts({ + roleAuthc, + ruleId, + alertIndexName: APM_ALERTS_INDEX, + connectorIndexName: APM_ACTION_VARIABLE_INDEX, + consumer: 'apm', + }) + ); it('indexes alert document with all group-by fields', async () => { expect(alerts[0]).property('service.name', 'opbeans-node'); diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts index 22bf6d8aa7f52..cc56d0f2e6684 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts @@ -12,6 +12,7 @@ export default function apmApiIntegrationTests({ }: DeploymentAgnosticFtrProviderContext) { describe('APM', function () { loadTestFile(require.resolve('./agent_explorer')); + loadTestFile(require.resolve('./alerts')); loadTestFile(require.resolve('./mobile')); loadTestFile(require.resolve('./custom_dashboards')); loadTestFile(require.resolve('./dependencies')); diff --git a/x-pack/test/api_integration/deployment_agnostic/services/alerting_api.ts b/x-pack/test/api_integration/deployment_agnostic/services/alerting_api.ts index 2956ee412a478..dd09804b5da83 100644 --- a/x-pack/test/api_integration/deployment_agnostic/services/alerting_api.ts +++ b/x-pack/test/api_integration/deployment_agnostic/services/alerting_api.ts @@ -11,8 +11,9 @@ import type { } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { MetricThresholdParams } from '@kbn/infra-plugin/common/alerting/metrics'; import { ThresholdParams } from '@kbn/observability-plugin/common/custom_threshold_rule/types'; +import { ApmRuleParamsType } from '@kbn/apm-plugin/common/rules/schema'; import { RoleCredentials } from '@kbn/ftr-common-functional-services'; -import type { Client } from '@elastic/elasticsearch'; +import { errors, type Client } from '@elastic/elasticsearch'; import type { TryWithRetriesOptions } from '@kbn/ftr-common-functional-services'; import { v4 as uuidv4 } from 'uuid'; import moment from 'moment'; @@ -613,17 +614,6 @@ export function AlertingApiProvider({ getService }: DeploymentAgnosticFtrProvide return body; }, - async findRuleById(roleAuthc: RoleCredentials, ruleId: string) { - if (!ruleId) { - throw new Error(`'ruleId' is undefined`); - } - const response = await supertestWithoutAuth - .get(`/api/alerting/rule/${ruleId}`) - .set(samlAuth.getInternalRequestHeader()) - .set(roleAuthc.apiKeyHeader); - return response.body || {}; - }, - waiting: { async waitForDocumentInIndex({ esClient, @@ -948,7 +938,6 @@ export function AlertingApiProvider({ getService }: DeploymentAgnosticFtrProvide return { helpers, - async waitForRuleStatus({ ruleId, expectedStatus, @@ -976,14 +965,27 @@ export function AlertingApiProvider({ getService }: DeploymentAgnosticFtrProvide async waitForDocumentInIndex({ indexName, docCountTarget = 1, + ruleId, }: { indexName: string; docCountTarget?: number; + ruleId?: string; }): Promise>> { return await retry.tryForTime(retryTimeout, async () => { const response = await es.search({ index: indexName, rest_total_hits_as_int: true, + ...(ruleId + ? { + body: { + query: { + term: { + 'kibana.alert.rule.uuid': ruleId, + }, + }, + }, + } + : {}), }); logger.debug(`Found ${response.hits.total} docs, looking for at least ${docCountTarget}.`); @@ -1064,7 +1066,15 @@ export function AlertingApiProvider({ getService }: DeploymentAgnosticFtrProvide }: { ruleTypeId: string; name: string; - params: MetricThresholdParams | ThresholdParams | SloBurnRateRuleParams; + params: + | CreateEsQueryRuleParams + | MetricThresholdParams + | ThresholdParams + | SloBurnRateRuleParams + | ApmRuleParamsType['apm.anomaly'] + | ApmRuleParamsType['apm.error_rate'] + | ApmRuleParamsType['apm.transaction_duration'] + | ApmRuleParamsType['apm.transaction_error_rate']; actions?: any[]; tags?: any[]; schedule?: { interval: string }; @@ -1096,5 +1106,103 @@ export function AlertingApiProvider({ getService }: DeploymentAgnosticFtrProvide .set(samlAuth.getInternalRequestHeader()); return response.body.data.find((obj: any) => obj.id === ruleId); }, + + async searchRules(roleAuthc: RoleCredentials, filter: string) { + return supertestWithoutAuth + .get('/api/alerting/rules/_find') + .query({ filter }) + .set(roleAuthc.apiKeyHeader) + .set(samlAuth.getInternalRequestHeader()); + }, + + async deleteRuleById({ roleAuthc, ruleId }: { roleAuthc: RoleCredentials; ruleId: string }) { + return supertestWithoutAuth + .delete(`/api/alerting/rule/${ruleId}`) + .set(roleAuthc.apiKeyHeader) + .set(samlAuth.getInternalRequestHeader()); + }, + + async deleteRules({ roleAuthc, filter }: { roleAuthc: RoleCredentials; filter: string }) { + const response = await this.searchRules(roleAuthc, filter); + return Promise.all( + response.body.data.map((rule: any) => this.deleteRuleById({ roleAuthc, ruleId: rule.id })) + ); + }, + + async deleteAllActionConnectors({ roleAuthc }: { roleAuthc: RoleCredentials }): Promise { + const res = await supertestWithoutAuth + .get(`/api/actions/connectors`) + .set(roleAuthc.apiKeyHeader) + .set(samlAuth.getInternalRequestHeader()); + + const body = res.body as Array<{ id: string; connector_type_id: string; name: string }>; + return Promise.all( + body.map(({ id }) => { + return this.deleteActionConnector({ + roleAuthc, + actionId: id, + }); + }) + ); + }, + + async deleteActionConnector({ + roleAuthc, + actionId, + }: { + roleAuthc: RoleCredentials; + actionId: string; + }) { + return supertestWithoutAuth + .delete(`/api/actions/connector/${actionId}`) + .set(roleAuthc.apiKeyHeader) + .set(samlAuth.getInternalRequestHeader()); + }, + + async cleanUpAlerts({ + roleAuthc, + ruleId, + consumer, + alertIndexName, + connectorIndexName, + }: { + roleAuthc: RoleCredentials; + ruleId: string; + consumer?: string; + alertIndexName?: string; + connectorIndexName?: string; + }) { + return Promise.allSettled([ + // Delete the rule by ID + this.deleteRuleById({ roleAuthc, ruleId }), + // Delete all documents in the alert index if specified + alertIndexName + ? es.deleteByQuery({ + index: alertIndexName, + conflicts: 'proceed', + query: { match_all: {} }, + }) + : Promise.resolve(), + // Delete event logs for the specified consumer if provided + consumer + ? es.deleteByQuery({ + index: '.kibana-event-log-*', + query: { term: { 'kibana.alert.rule.consumer': consumer } }, + }) + : Promise.resolve(), + // Delete connector index if provided + connectorIndexName + ? es.indices.delete({ index: connectorIndexName }).catch((e) => { + if (e instanceof errors.ResponseError && e.statusCode === 404) { + return; + } + + throw e; + }) + : Promise.resolve(), + // Delete all action connectors + this.deleteAllActionConnectors({ roleAuthc }), + ]); + }, }; } diff --git a/x-pack/test/api_integration/deployment_agnostic/services/apm_api.ts b/x-pack/test/api_integration/deployment_agnostic/services/apm_api.ts index 26d92997a6021..c3f43b57902e8 100644 --- a/x-pack/test/api_integration/deployment_agnostic/services/apm_api.ts +++ b/x-pack/test/api_integration/deployment_agnostic/services/apm_api.ts @@ -135,3 +135,5 @@ export function ApmApiProvider(context: DeploymentAgnosticFtrProviderContext) { writeUser: createApmApiClient(context, 'editor'), }; } + +export type ApmApiClient = ReturnType; diff --git a/x-pack/test/apm_api_integration/tests/alerts/anomaly_alert.spec.ts b/x-pack/test/apm_api_integration/tests/alerts/anomaly_alert.spec.ts index 033d64e8f12e8..e88115389f585 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/anomaly_alert.spec.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/anomaly_alert.spec.ts @@ -12,12 +12,12 @@ import { apm, timerange } from '@kbn/apm-synthtrace-client'; import expect from '@kbn/expect'; import { range } from 'lodash'; import { ML_ANOMALY_SEVERITY } from '@kbn/ml-anomaly-utils/anomaly_severity'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { createAndRunApmMlJobs } from '../../common/utils/create_and_run_apm_ml_jobs'; -import { createApmRule } from './helpers/alerting_api_helper'; -import { waitForActiveRule } from './helpers/wait_for_active_rule'; import { waitForAlertsForRule } from './helpers/wait_for_alerts_for_rule'; +import { waitForActiveRule } from './helpers/wait_for_active_rule'; +import { createApmRule } from './helpers/alerting_api_helper'; import { cleanupRuleAndAlertState } from './helpers/cleanup_rule_and_alert_state'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { createAndRunApmMlJobs } from '../../common/utils/create_and_run_apm_ml_jobs'; export default function ApiTest({ getService }: FtrProviderContext) { const registry = getService('registry'); diff --git a/x-pack/test/apm_api_integration/tests/alerts/helpers/alerting_api_helper.ts b/x-pack/test/apm_api_integration/tests/alerts/helpers/alerting_api_helper.ts index 5da6ee4f860d0..86544981bbdb4 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/helpers/alerting_api_helper.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/helpers/alerting_api_helper.ts @@ -11,13 +11,11 @@ import pRetry from 'p-retry'; import type { Agent as SuperTestAgent } from 'supertest'; import { ApmRuleType } from '@kbn/rule-data-utils'; import { ApmRuleParamsType } from '@kbn/apm-plugin/common/rules/schema'; -import { ApmDocumentType } from '@kbn/apm-plugin/common/document_type'; -import { RollupInterval } from '@kbn/apm-plugin/common/rollup'; import { ObservabilityApmAlert } from '@kbn/alerts-as-data-utils'; -import { ApmApiClient } from '../../../common/config'; - -export const APM_ALERTS_INDEX = '.alerts-observability.apm.alerts-*'; -export const APM_ACTION_VARIABLE_INDEX = 'apm-index-connector-test'; +import { + APM_ACTION_VARIABLE_INDEX, + APM_ALERTS_INDEX, +} from '../../../../api_integration/deployment_agnostic/apis/observability/apm/alerts/helpers/alerting_helper'; export async function createApmRule({ supertest, @@ -53,59 +51,6 @@ export async function createApmRule({ } } -function getTimerange() { - return { - start: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), - end: new Date(Date.now() + 5 * 60 * 1000).toISOString(), - }; -} - -export async function fetchServiceInventoryAlertCounts(apmApiClient: ApmApiClient) { - const timerange = getTimerange(); - const serviceInventoryResponse = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/services', - params: { - query: { - ...timerange, - environment: 'ENVIRONMENT_ALL', - kuery: '', - probability: 1, - documentType: ApmDocumentType.ServiceTransactionMetric, - rollupInterval: RollupInterval.SixtyMinutes, - useDurationSummary: true, - }, - }, - }); - - return serviceInventoryResponse.body.items.reduce>((acc, item) => { - return { ...acc, [item.serviceName]: item.alertsCount ?? 0 }; - }, {}); -} - -export async function fetchServiceTabAlertCount({ - apmApiClient, - serviceName, -}: { - apmApiClient: ApmApiClient; - serviceName: string; -}) { - const timerange = getTimerange(); - const alertsCountReponse = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/services/{serviceName}/alerts_count', - params: { - path: { - serviceName, - }, - query: { - ...timerange, - environment: 'ENVIRONMENT_ALL', - }, - }, - }); - - return alertsCountReponse.body.alertsCount; -} - export async function runRuleSoon({ ruleId, supertest, @@ -159,71 +104,6 @@ export async function deleteApmRules(supertest: SuperTestAgent) { ); } -export function deleteApmAlerts(es: Client) { - return es.deleteByQuery({ - index: APM_ALERTS_INDEX, - conflicts: 'proceed', - query: { match_all: {} }, - }); -} - -export async function clearKibanaApmEventLog(es: Client) { - return es.deleteByQuery({ - index: '.kibana-event-log-*', - query: { term: { 'kibana.alert.rule.consumer': 'apm' } }, - }); -} - -export type ApmAlertFields = ParsedTechnicalFields & ObservabilityApmAlert; - -export async function createIndexConnector({ - supertest, - name, -}: { - supertest: SuperTestAgent; - name: string; -}) { - const { body } = await supertest - .post(`/api/actions/connector`) - .set('kbn-xsrf', 'foo') - .send({ - name, - config: { - index: APM_ACTION_VARIABLE_INDEX, - refresh: true, - }, - connector_type_id: '.index', - }); - - return body.id as string; -} - -export function getIndexAction({ - actionId, - actionVariables, -}: { - actionId: string; - actionVariables: Array<{ name: string }>; -}) { - return { - group: 'threshold_met', - id: actionId, - params: { - documents: [ - actionVariables.reduce>((acc, actionVariable) => { - acc[actionVariable.name] = `{{context.${actionVariable.name}}}`; - return acc; - }, {}), - ], - }, - frequency: { - notify_when: 'onActionGroupChange', - throttle: null, - summary: false, - }, - }; -} - export async function deleteAllActionConnectors({ supertest, es, @@ -241,6 +121,23 @@ export async function deleteAllActionConnectors({ ); } +export function deleteApmAlerts(es: Client) { + return es.deleteByQuery({ + index: APM_ALERTS_INDEX, + conflicts: 'proceed', + query: { match_all: {} }, + }); +} + +export async function clearKibanaApmEventLog(es: Client) { + return es.deleteByQuery({ + index: '.kibana-event-log-*', + query: { term: { 'kibana.alert.rule.consumer': 'apm' } }, + }); +} + +export type ApmAlertFields = ParsedTechnicalFields & ObservabilityApmAlert; + async function deleteActionConnector({ supertest, actionId, diff --git a/x-pack/test/apm_api_integration/tests/alerts/helpers/cleanup_rule_and_alert_state.ts b/x-pack/test/apm_api_integration/tests/alerts/helpers/cleanup_rule_and_alert_state.ts index 2fae6c9643ff7..b41e59cd4b774 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/helpers/cleanup_rule_and_alert_state.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/helpers/cleanup_rule_and_alert_state.ts @@ -9,12 +9,11 @@ import { Client } from '@elastic/elasticsearch'; import { ToolingLog } from '@kbn/tooling-log'; import type { Agent as SuperTestAgent } from 'supertest'; import { + deleteActionConnectorIndex, clearKibanaApmEventLog, - deleteApmRules, deleteApmAlerts, - deleteActionConnectorIndex, - deleteAllActionConnectors, } from './alerting_api_helper'; +import { deleteApmRules, deleteAllActionConnectors } from './alerting_api_helper'; export async function cleanupRuleAndAlertState({ es, diff --git a/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_active_apm_alerts.ts b/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_active_apm_alerts.ts index 9f83b4850dd40..e342e31ee0fa3 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_active_apm_alerts.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_active_apm_alerts.ts @@ -5,9 +5,9 @@ * 2.0. */ import type { Client } from '@elastic/elasticsearch'; -import pRetry from 'p-retry'; import { ToolingLog } from '@kbn/tooling-log'; -import { APM_ALERTS_INDEX } from './alerting_api_helper'; +import pRetry from 'p-retry'; +import { APM_ALERTS_INDEX } from '../../../../api_integration/deployment_agnostic/apis/observability/apm/alerts/helpers/alerting_helper'; export async function getActiveApmAlerts({ ruleId, diff --git a/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_alerts_for_rule.ts b/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_alerts_for_rule.ts index 334631b354cd1..28437e4edbc62 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_alerts_for_rule.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_alerts_for_rule.ts @@ -11,7 +11,10 @@ import type { SearchResponse, } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import pRetry from 'p-retry'; -import { ApmAlertFields, APM_ALERTS_INDEX } from './alerting_api_helper'; +import { + APM_ALERTS_INDEX, + ApmAlertFields, +} from '../../../../api_integration/deployment_agnostic/apis/observability/apm/alerts/helpers/alerting_helper'; async function getAlertByRuleId({ es, ruleId }: { es: Client; ruleId: string }) { const response = (await es.search({ diff --git a/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_index_connector_results.ts b/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_index_connector_results.ts index 9646289420804..b6634e3a33f2c 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_index_connector_results.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/helpers/wait_for_index_connector_results.ts @@ -7,7 +7,7 @@ import { Client } from '@elastic/elasticsearch'; import pRetry from 'p-retry'; -import { APM_ACTION_VARIABLE_INDEX } from './alerting_api_helper'; +import { APM_ACTION_VARIABLE_INDEX } from '../../../../api_integration/deployment_agnostic/apis/observability/apm/alerts/helpers/alerting_helper'; async function getIndexConnectorResults(es: Client) { const res = await es.search({ index: APM_ACTION_VARIABLE_INDEX }); diff --git a/x-pack/test/apm_api_integration/tests/alerts/preview_chart_error_rate.spec.ts b/x-pack/test/apm_api_integration/tests/alerts/preview_chart_error_rate.spec.ts deleted file mode 100644 index 3af62d826fd31..0000000000000 --- a/x-pack/test/apm_api_integration/tests/alerts/preview_chart_error_rate.spec.ts +++ /dev/null @@ -1,599 +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 { - SERVICE_ENVIRONMENT, - SERVICE_NAME, - TRANSACTION_NAME, - TRANSACTION_TYPE, -} from '@kbn/apm-plugin/common/es_fields/apm'; -import type { PreviewChartResponseItem } from '@kbn/apm-plugin/server/routes/alerts/route'; -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { generateErrorData } from './generate_data'; - -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const apmApiClient = getService('apmApiClient'); - const apmSynthtraceEsClient = getService('apmSynthtraceEsClient'); - const start = new Date('2021-01-01T00:00:00.000Z').getTime(); - const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; - - const getOptions = () => ({ - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceName: 'synth-go', - transactionType: 'request', - environment: 'ENVIRONMENT_ALL', - interval: '5m', - }, - }, - }); - - const getOptionsWithFilterQuery = () => ({ - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - interval: '5m', - searchConfiguration: JSON.stringify({ - query: { - query: 'service.name: synth-go and transaction.type: request', - language: 'kuery', - }, - }), - serviceName: undefined, - transactionType: undefined, - transactionName: undefined, - environment: 'ENVIRONMENT_ALL', - }, - }, - }); - - registry.when(`without data loaded`, { config: 'basic', archives: [] }, () => { - it('transaction_error_rate without data', async () => { - const options = getOptions(); - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - ...options, - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series).to.eql([]); - }); - }); - - registry.when(`with data loaded`, { config: 'basic', archives: [] }, () => { - // FLAKY: https://github.com/elastic/kibana/issues/176977 - describe('transaction_error_rate: with data loaded', () => { - before(async () => { - await generateErrorData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }); - await generateErrorData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }); - }); - - after(() => apmSynthtraceEsClient.clean()); - - it('with data', async () => { - const options = getOptions(); - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - ...options, - }); - - expect(response.status).to.be(200); - expect( - response.body.errorRateChartPreview.series.some((item: PreviewChartResponseItem) => - item.data.some((coordinate) => coordinate.x && coordinate.y) - ) - ).to.equal(true); - }); - - it('with transaction name', async () => { - const options = { - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceName: 'synth-go', - transactionName: 'GET /banana', - transactionType: 'request', - environment: 'ENVIRONMENT_ALL', - interval: '5m', - }, - }, - }; - - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - ...options, - }); - - expect(response.status).to.be(200); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 50 }]); - }); - - it('with nonexistent transaction name', async () => { - const options = { - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceName: 'synth-go', - transactionName: 'foo', - transactionType: 'request', - environment: 'ENVIRONMENT_ALL', - interval: '5m', - }, - }, - }; - - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - ...options, - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series).to.eql([]); - }); - - it('with no group by parameter', async () => { - const options = getOptions(); - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series.length).to.equal(1); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 37.5 }]); - }); - - it('with default group by fields', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series.length).to.equal(1); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 37.5 }]); - }); - - it('with group by on transaction name', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series.length).to.equal(2); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { - name: 'synth-go_production_request_GET /banana', - y: 50, - }, - { - name: 'synth-go_production_request_GET /apple', - y: 25, - }, - ]); - }); - - it('with group by on transaction name and filter on transaction name', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - transactionName: 'GET /apple', - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series.length).to.equal(1); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request_GET /apple', y: 25 }]); - }); - - it.skip('with empty service name, transaction name and transaction type', async () => { - const options = { - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceName: '', - transactionName: '', - transactionType: '', - environment: 'ENVIRONMENT_ALL', - interval: '5m', - }, - }, - }; - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { name: 'synth-go_production_request', y: 37.5 }, - { name: 'synth-java_production_request', y: 37.5 }, - ]); - }); - - it('with empty service name, transaction name, transaction type and group by on transaction name', async () => { - const options = { - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceName: '', - transactionName: '', - transactionType: '', - environment: 'ENVIRONMENT_ALL', - interval: '5m', - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { - name: 'synth-go_production_request_GET /banana', - y: 50, - }, - { - name: 'synth-java_production_request_GET /banana', - y: 50, - }, - { - name: 'synth-go_production_request_GET /apple', - y: 25, - }, - { - name: 'synth-java_production_request_GET /apple', - y: 25, - }, - ]); - }); - }); - }); - - registry.when(`with data loaded and using KQL filter`, { config: 'basic', archives: [] }, () => { - // FLAKY: https://github.com/elastic/kibana/issues/176983 - describe('transaction_error_rate: with data loaded and using KQL filter', () => { - before(async () => { - await generateErrorData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }); - await generateErrorData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }); - }); - - after(() => apmSynthtraceEsClient.clean()); - - it('with data', async () => { - const options = getOptionsWithFilterQuery(); - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - ...options, - }); - - expect(response.status).to.be(200); - expect( - response.body.errorRateChartPreview.series.some((item: PreviewChartResponseItem) => - item.data.some((coordinate) => coordinate.x && coordinate.y) - ) - ).to.equal(true); - }); - - it('with transaction name in filter query', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: - 'service.name: synth-go and transaction.type: request and transaction.name: GET /banana', - language: 'kuery', - }, - }), - }, - }, - }; - - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - ...options, - }); - - expect(response.status).to.be(200); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 50 }]); - }); - - it('with nonexistent transaction name', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: - 'service.name: synth-go and transaction.type: request and transaction.name: foo', - language: 'kuery', - }, - }), - }, - }, - }; - - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - ...options, - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series).to.eql([]); - }); - - it('with no group by parameter', async () => { - const options = getOptionsWithFilterQuery(); - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series.length).to.equal(1); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 37.5 }]); - }); - - it('with default group by fields', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series.length).to.equal(1); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 37.5 }]); - }); - - it('with group by on transaction name', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series.length).to.equal(2); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { - name: 'synth-go_production_request_GET /banana', - y: 50, - }, - { - name: 'synth-go_production_request_GET /apple', - y: 25, - }, - ]); - }); - - it('with group by on transaction name and filter on transaction name', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: - 'service.name: synth-go and transaction.type: request and transaction.name: GET /apple', - language: 'kuery', - }, - }), - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.errorRateChartPreview.series.length).to.equal(1); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request_GET /apple', y: 25 }]); - }); - - it('with empty filter query', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: '', - language: 'kuery', - }, - }), - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { name: 'synth-go_production_request', y: 37.5 }, - { name: 'synth-java_production_request', y: 37.5 }, - ]); - }); - - it.skip('with empty filter query and group by on transaction name', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: '', - language: 'kuery', - }, - }), - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_error_rate/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.errorRateChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { - name: 'synth-go_production_request_GET /banana', - y: 50, - }, - { - name: 'synth-java_production_request_GET /banana', - y: 50, - }, - { - name: 'synth-go_production_request_GET /apple', - y: 25, - }, - { - name: 'synth-java_production_request_GET /apple', - y: 25, - }, - ]); - }); - }); - }); -} diff --git a/x-pack/test/apm_api_integration/tests/alerts/preview_chart_transaction_duration.spec.ts b/x-pack/test/apm_api_integration/tests/alerts/preview_chart_transaction_duration.spec.ts deleted file mode 100644 index a677ce11cdb0c..0000000000000 --- a/x-pack/test/apm_api_integration/tests/alerts/preview_chart_transaction_duration.spec.ts +++ /dev/null @@ -1,556 +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 { - SERVICE_ENVIRONMENT, - SERVICE_NAME, - TRANSACTION_NAME, - TRANSACTION_TYPE, -} from '@kbn/apm-plugin/common/es_fields/apm'; -import type { PreviewChartResponseItem } from '@kbn/apm-plugin/server/routes/alerts/route'; -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { generateLatencyData } from './generate_data'; - -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const apmApiClient = getService('apmApiClient'); - const apmSynthtraceEsClient = getService('apmSynthtraceEsClient'); - const start = new Date('2021-01-01T00:00:00.000Z').getTime(); - const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; - - const getOptions = () => ({ - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - serviceName: 'synth-go', - transactionType: 'request', - environment: 'ENVIRONMENT_ALL', - interval: '5m', - }, - }, - }); - - const getOptionsWithFilterQuery = () => ({ - params: { - query: { - start: new Date(start).toISOString(), - end: new Date(end).toISOString(), - interval: '5m', - searchConfiguration: JSON.stringify({ - query: { - query: 'service.name: synth-go and transaction.type: request', - language: 'kuery', - }, - }), - serviceName: undefined, - transactionType: undefined, - transactionName: undefined, - environment: 'ENVIRONMENT_ALL', - }, - }, - }); - - registry.when(`without data loaded`, { config: 'basic', archives: [] }, () => { - it('transaction_duration (without data)', async () => { - const options = getOptions(); - - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - ...options, - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series).to.eql([]); - }); - }); - - // FLAKY: https://github.com/elastic/kibana/issues/176989 - registry.when(`with data loaded`, { config: 'basic', archives: [] }, () => { - // FLAKY: https://github.com/elastic/kibana/issues/176986 - // Failing: See https://github.com/elastic/kibana/issues/176989 - describe('transaction_duration: with data loaded', () => { - before(async () => { - await generateLatencyData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }); - await generateLatencyData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }); - }); - - after(() => apmSynthtraceEsClient.clean()); - - it('with data', async () => { - const options = getOptions(); - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.latencyChartPreview.series.some((item: PreviewChartResponseItem) => - item.data.some((coordinate) => coordinate.x && coordinate.y) - ) - ).to.equal(true); - }); - - it('with transaction name', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - transactionName: 'GET /banana', - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 5000 }]); - }); - - it('with nonexistent transaction name', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - transactionName: 'foo', - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series).to.eql([]); - }); - - it('with no group by parameter', async () => { - const options = getOptions(); - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(1); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 7500 }]); - }); - - it('with default group by fields', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(1); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 7500 }]); - }); - - it('with group by on transaction name', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(2); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { name: 'synth-go_production_request_GET /apple', y: 10000 }, - { name: 'synth-go_production_request_GET /banana', y: 5000 }, - ]); - }); - - it('with group by on transaction name and filter on transaction name', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - transactionName: 'GET /apple', - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(1); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request_GET /apple', y: 10000 }]); - }); - - it('with empty service name, transaction name and transaction type', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - serviceName: '', - transactionName: '', - transactionType: '', - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { name: 'synth-go_production_request', y: 7500 }, - { name: 'synth-java_production_request', y: 7500 }, - ]); - }); - - it('with empty service name, transaction name, transaction type and group by on transaction name', async () => { - const options = { - params: { - query: { - ...getOptions().params.query, - serviceName: '', - transactionName: '', - transactionType: '', - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(4); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { name: 'synth-go_production_request_GET /apple', y: 10000 }, - { name: 'synth-java_production_request_GET /apple', y: 10000 }, - { name: 'synth-go_production_request_GET /banana', y: 5000 }, - { name: 'synth-java_production_request_GET /banana', y: 5000 }, - ]); - }); - }); - }); - - // FLAKY: https://github.com/elastic/kibana/issues/176989 - registry.when(`with data loaded and using KQL filter`, { config: 'basic', archives: [] }, () => { - describe('transaction_duration: with data loaded and using KQL filter', () => { - before(async () => { - await generateLatencyData({ serviceName: 'synth-go', start, end, apmSynthtraceEsClient }); - await generateLatencyData({ serviceName: 'synth-java', start, end, apmSynthtraceEsClient }); - }); - - after(() => apmSynthtraceEsClient.clean()); - - it('with data', async () => { - const options = getOptionsWithFilterQuery(); - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.latencyChartPreview.series.some((item: PreviewChartResponseItem) => - item.data.some((coordinate) => coordinate.x && coordinate.y) - ) - ).to.equal(true); - }); - - it('with transaction name in filter query', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: - 'service.name: synth-go and transaction.type: request and transaction.name: GET /banana', - language: 'kuery', - }, - }), - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 5000 }]); - }); - - it('with nonexistent transaction name', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: - 'service.name: synth-go and transaction.type: request and transaction.name: foo', - language: 'kuery', - }, - }), - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series).to.eql([]); - }); - - it('with no group by parameter', async () => { - const options = getOptionsWithFilterQuery(); - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(1); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 7500 }]); - }); - - it('with default group by fields', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(1); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request', y: 7500 }]); - }); - - it('with group by on transaction name', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(2); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { name: 'synth-go_production_request_GET /apple', y: 10000 }, - { name: 'synth-go_production_request_GET /banana', y: 5000 }, - ]); - }); - - it('with group by on transaction name and filter on transaction name', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: - 'service.name: synth-go and transaction.type: request and transaction.name: GET /apple', - language: 'kuery', - }, - }), - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(1); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([{ name: 'synth-go_production_request_GET /apple', y: 10000 }]); - }); - - it('with empty filter query', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: '', - language: 'kuery', - }, - }), - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { name: 'synth-go_production_request', y: 7500 }, - { name: 'synth-java_production_request', y: 7500 }, - ]); - }); - - it('with empty filter query and group by on transaction name', async () => { - const options = { - params: { - query: { - ...getOptionsWithFilterQuery().params.query, - searchConfiguration: JSON.stringify({ - query: { - query: '', - language: 'kuery', - }, - }), - groupBy: [SERVICE_NAME, SERVICE_ENVIRONMENT, TRANSACTION_TYPE, TRANSACTION_NAME], - }, - }, - }; - - const response = await apmApiClient.readUser({ - ...options, - endpoint: 'GET /internal/apm/rule_types/transaction_duration/chart_preview', - }); - - expect(response.status).to.be(200); - expect(response.body.latencyChartPreview.series.length).to.equal(4); - expect( - response.body.latencyChartPreview.series.map((item: PreviewChartResponseItem) => ({ - name: item.name, - y: item.data[0].y, - })) - ).to.eql([ - { name: 'synth-go_production_request_GET /apple', y: 10000 }, - { name: 'synth-java_production_request_GET /apple', y: 10000 }, - { name: 'synth-go_production_request_GET /banana', y: 5000 }, - { name: 'synth-java_production_request_GET /banana', y: 5000 }, - ]); - }); - }); - }); -} diff --git a/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts b/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts index 044006e273348..d39724b0570b2 100644 --- a/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts +++ b/x-pack/test/apm_api_integration/tests/service_groups/service_group_count/service_group_count.spec.ts @@ -7,10 +7,10 @@ import { AggregationType } from '@kbn/apm-plugin/common/rules/apm_rule_types'; import { ApmRuleType } from '@kbn/rule-data-utils'; import expect from '@kbn/expect'; +import { waitForActiveApmAlert } from '../../alerts/helpers/wait_for_active_apm_alerts'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; import { createApmRule } from '../../alerts/helpers/alerting_api_helper'; import { cleanupRuleAndAlertState } from '../../alerts/helpers/cleanup_rule_and_alert_state'; -import { waitForActiveApmAlert } from '../../alerts/helpers/wait_for_active_apm_alerts'; import { createServiceGroupApi, deleteAllServiceGroups, diff --git a/x-pack/test/apm_api_integration/tests/services/service_alerts.spec.ts b/x-pack/test/apm_api_integration/tests/services/service_alerts.spec.ts index 958c2ed88f460..e3324546c84d5 100644 --- a/x-pack/test/apm_api_integration/tests/services/service_alerts.spec.ts +++ b/x-pack/test/apm_api_integration/tests/services/service_alerts.spec.ts @@ -8,10 +8,10 @@ import expect from '@kbn/expect'; import { AggregationType } from '@kbn/apm-plugin/common/rules/apm_rule_types'; import { ApmRuleType } from '@kbn/rule-data-utils'; import { apm, timerange } from '@kbn/apm-synthtrace-client'; +import { waitForAlertsForRule } from '../alerts/helpers/wait_for_alerts_for_rule'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createApmRule, runRuleSoon, ApmAlertFields } from '../alerts/helpers/alerting_api_helper'; import { waitForActiveRule } from '../alerts/helpers/wait_for_active_rule'; -import { waitForAlertsForRule } from '../alerts/helpers/wait_for_alerts_for_rule'; import { cleanupRuleAndAlertState } from '../alerts/helpers/cleanup_rule_and_alert_state'; export default function ServiceAlerts({ getService }: FtrProviderContext) { diff --git a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_alerts.spec.ts b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_alerts.spec.ts index 6c009682e1421..f6b2c7c3a74a7 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_alerts.spec.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_alerts.spec.ts @@ -13,10 +13,10 @@ import { RollupInterval } from '@kbn/apm-plugin/common/rollup'; import { apm, timerange } from '@kbn/apm-synthtrace-client'; import { AggregationType } from '@kbn/apm-plugin/common/rules/apm_rule_types'; import { ApmRuleType } from '@kbn/rule-data-utils'; +import { waitForAlertsForRule } from '../alerts/helpers/wait_for_alerts_for_rule'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createApmRule, runRuleSoon, ApmAlertFields } from '../alerts/helpers/alerting_api_helper'; import { waitForActiveRule } from '../alerts/helpers/wait_for_active_rule'; -import { waitForAlertsForRule } from '../alerts/helpers/wait_for_alerts_for_rule'; import { cleanupRuleAndAlertState } from '../alerts/helpers/cleanup_rule_and_alert_state'; type TransactionsGroupsMainStatistics = From a10eb1fe4e55aa0cfbbb4b12a8d740a867463283 Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Tue, 12 Nov 2024 14:19:22 +0300 Subject: [PATCH 014/105] [UA][Core] Surface integrations with internal APIs in upgrade assistant (#199026) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary > In https://github.com/elastic/kibana/issues/117241 we're surfacing usage of APIs marked as `deprecated: true` in the Upgrade Assistant to help users prepare for a major upgrade. While internal APIs aren't really deprecated in the same sense we are making a breaking change by blocking external integrations with these APIs. Since this could be equally disruptive to users depending on these APIs it would help our users to surface such usage in the UA too. The `api` deprecations now have two sub types: 1. routes deprecations `options.deprecated: { … }` 2. access deprecations `options.access: 'internal'` This PR adds the second `api` deprecation subtype. The reason i kept one `api` deprecation type and i didnt create a new type is that they have exactly the same registration process but are triggered by different attributes. The `api` deprecation is fully managed by the core team internal services and are configured by the user through the route interface so it makes sense to keep them as one type. I also can see us adding more subtypes to this and just piggybacking on the current flow instead of duplicating it everytime. **Checklist** - [x] Create deprecation subtype - [x] Example plugin - [x] Surface the deprecation in UA - [x] Api access deprecation copy (@florent-leborgne ) - [x] Update README and code annotations - [x] Unit tests - [x] Integration tests Closes https://github.com/elastic/kibana/issues/194675 ### Design decisions: If the API has both route deprecation (`options.deprecated: { … }` ) AND is an internal api `options.access: 'internal'` The current behavior i went for in my PR: I show this API once in the UA under the internal access deprecation. While showing the route deprecation details if defined. This seems to make the most sense since users should stop using this API altogether. ### Copy decisions: @florent-leborgne wrote the copy for this deprecation subtype. image image ## Testing Run kibana locally with the test example plugin that has deprecated routes ``` yarn start --plugin-path=examples/routing_example --plugin-path=examples/developer_examples ``` The following comprehensive deprecated routes examples are registered inside the folder: `examples/routing_example/server/routes/deprecated_routes` Run them in the dev console to trigger the deprecation condition so they show up in the UA: ``` GET kbn:/api/routing_example/d/internal_deprecated_route?elasticInternalOrigin=false GET kbn:/internal/routing_example/d/internal_only_route?elasticInternalOrigin=false GET kbn:/internal/routing_example/d/internal_versioned_route?apiVersion=1&elasticInternalOrigin=false ``` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- examples/routing_example/common/index.ts | 5 +- .../server/routes/deprecated_routes/index.ts | 2 + .../routes/deprecated_routes/internal.ts | 54 +++++++ .../routes/deprecated_routes/versioned.ts | 98 ++++++++---- .../server/routes/message_routes.ts | 3 + .../core-deprecations-common/index.ts | 1 + .../core-deprecations-common/src/types.ts | 2 +- .../src/deprecations/api_deprecations.ts | 96 ------------ .../access/access_deprecations.ts | 62 ++++++++ .../api_deprecations/access/i18n_texts.ts | 101 ++++++++++++ .../api_deprecations/access/index.ts | 10 ++ .../api_deprecation_id.test.ts | 51 ++++++ .../api_deprecations/api_deprecation_id.ts | 22 +++ .../deprecations/api_deprecations/index.ts | 13 ++ .../register_api_depercation_info.test.ts} | 66 ++------ .../register_api_depercation_info.ts | 70 +++++++++ .../route}/i18n_texts.ts | 67 ++++---- .../api_deprecations/route/index.ts | 10 ++ .../route/route_deprecations.ts | 65 ++++++++ .../deprecations/api_deprecations/types.ts | 25 +++ .../src/deprecations/index.ts | 7 +- .../src/deprecations_service.test.ts | 5 +- .../src/routes/get.ts | 3 + .../src/routes/post_validation_handler.ts | 11 +- .../src/routes/resolve_deprecated_api.ts | 3 + .../src/request.ts | 9 +- .../src/router.ts | 23 ++- .../versioned_router/core_versioned_route.ts | 12 +- .../src/http_server.ts | 21 ++- .../src/lifecycle_handlers.test.ts | 27 ++++ .../core-http-server-internal/src/types.ts | 10 +- packages/core/http/core-http-server/index.ts | 5 +- .../core-http-server/src/http_contract.ts | 8 +- .../http/core-http-server/src/router/index.ts | 10 +- .../http/core-http-server/src/router/route.ts | 9 ++ .../core-http-server/src/router/router.ts | 19 ++- .../src/core_usage_stats.ts | 3 + .../collectors/core/core_usage_collector.ts | 12 ++ src/plugins/telemetry/schema/oss_plugins.json | 24 ++- x-pack/plugins/upgrade_assistant/README.md | 34 ++-- .../upgrade_assistant/api_deprecations.ts | 145 +++++++++++++----- 41 files changed, 916 insertions(+), 307 deletions(-) create mode 100644 examples/routing_example/server/routes/deprecated_routes/internal.ts delete mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.ts create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/access_deprecations.ts create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/i18n_texts.ts create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/index.ts create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/api_deprecation_id.test.ts create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/api_deprecation_id.ts create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/index.ts rename packages/core/deprecations/core-deprecations-server-internal/src/deprecations/{api_deprecations.test.ts => api_deprecations/register_api_depercation_info.test.ts} (89%) create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/register_api_depercation_info.ts rename packages/core/deprecations/core-deprecations-server-internal/src/deprecations/{ => api_deprecations/route}/i18n_texts.ts (67%) create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/index.ts create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/route_deprecations.ts create mode 100644 packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/types.ts diff --git a/examples/routing_example/common/index.ts b/examples/routing_example/common/index.ts index 5bec77ebe0c0f..205144ad0f872 100644 --- a/examples/routing_example/common/index.ts +++ b/examples/routing_example/common/index.ts @@ -20,5 +20,8 @@ export const DEPRECATED_ROUTES = { DEPRECATED_ROUTE: '/api/routing_example/d/deprecated_route', REMOVED_ROUTE: '/api/routing_example/d/removed_route', MIGRATED_ROUTE: '/api/routing_example/d/migrated_route', - VERSIONED_ROUTE: '/api/routing_example/d/versioned', + VERSIONED_ROUTE: '/api/routing_example/d/versioned_route', + INTERNAL_DEPRECATED_ROUTE: '/api/routing_example/d/internal_deprecated_route', + INTERNAL_ONLY_ROUTE: '/internal/routing_example/d/internal_only_route', + VERSIONED_INTERNAL_ROUTE: '/internal/routing_example/d/internal_versioned_route', }; diff --git a/examples/routing_example/server/routes/deprecated_routes/index.ts b/examples/routing_example/server/routes/deprecated_routes/index.ts index 75dc0261ed1b9..3fa535b171d9a 100644 --- a/examples/routing_example/server/routes/deprecated_routes/index.ts +++ b/examples/routing_example/server/routes/deprecated_routes/index.ts @@ -10,8 +10,10 @@ import { IRouter } from '@kbn/core/server'; import { registerDeprecatedRoute } from './unversioned'; import { registerVersionedDeprecatedRoute } from './versioned'; +import { registerInternalDeprecatedRoute } from './internal'; export function registerDeprecatedRoutes(router: IRouter) { registerDeprecatedRoute(router); registerVersionedDeprecatedRoute(router); + registerInternalDeprecatedRoute(router); } diff --git a/examples/routing_example/server/routes/deprecated_routes/internal.ts b/examples/routing_example/server/routes/deprecated_routes/internal.ts new file mode 100644 index 0000000000000..95267cb66dd38 --- /dev/null +++ b/examples/routing_example/server/routes/deprecated_routes/internal.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import type { IRouter } from '@kbn/core/server'; +import { DEPRECATED_ROUTES } from '../../../common'; + +export const registerInternalDeprecatedRoute = (router: IRouter) => { + router.get( + { + path: DEPRECATED_ROUTES.INTERNAL_DEPRECATED_ROUTE, + validate: false, + options: { + // Explicitly set access is to internal + access: 'internal', + deprecated: { + documentationUrl: 'https://elastic.co/', + severity: 'critical', + message: 'Additonal message for internal deprecated api', + reason: { type: 'deprecate' }, + }, + }, + }, + async (ctx, req, res) => { + return res.ok({ + body: { + result: + 'Called deprecated route with `access: internal`. Check UA to see the deprecation.', + }, + }); + } + ); + + router.get( + { + path: DEPRECATED_ROUTES.INTERNAL_ONLY_ROUTE, + validate: false, + // If no access is specified then it defaults to internal + }, + async (ctx, req, res) => { + return res.ok({ + body: { + result: + 'Called route with `access: internal` Although this API is not marked as deprecated it will show in UA. Check UA to see the deprecation.', + }, + }); + } + ); +}; diff --git a/examples/routing_example/server/routes/deprecated_routes/versioned.ts b/examples/routing_example/server/routes/deprecated_routes/versioned.ts index 060bc64403dba..6261ef6f9cb91 100644 --- a/examples/routing_example/server/routes/deprecated_routes/versioned.ts +++ b/examples/routing_example/server/routes/deprecated_routes/versioned.ts @@ -11,42 +11,72 @@ import type { IRouter } from '@kbn/core/server'; import { DEPRECATED_ROUTES } from '../../../common'; export const registerVersionedDeprecatedRoute = (router: IRouter) => { - const versionedRoute = router.versioned.get({ - path: DEPRECATED_ROUTES.VERSIONED_ROUTE, - description: 'Routing example plugin deprecated versioned route.', - access: 'internal', - options: { - excludeFromOAS: true, - }, - enableQueryVersion: true, - }); - - versionedRoute.addVersion( - { + router.versioned + .get({ + path: DEPRECATED_ROUTES.VERSIONED_ROUTE, + description: 'Routing example plugin deprecated versioned route.', + access: 'public', options: { - deprecated: { - documentationUrl: 'https://elastic.co/', - severity: 'warning', - reason: { type: 'bump', newApiVersion: '2' }, + excludeFromOAS: true, + }, + enableQueryVersion: true, + }) + .addVersion( + { + options: { + deprecated: { + documentationUrl: 'https://elastic.co/', + severity: 'warning', + reason: { type: 'deprecate' }, + }, }, + validate: false, + version: '2023-10-31', }, - validate: false, - version: '1', - }, - (ctx, req, res) => { - return res.ok({ - body: { result: 'Called deprecated version of the API. API version 1 -> 2' }, - }); - } - ); + (ctx, req, res) => { + return res.ok({ + body: { result: 'Called deprecated version of the API "2023-10-31"' }, + }); + } + ); - versionedRoute.addVersion( - { - version: '2', - validate: false, - }, - (ctx, req, res) => { - return res.ok({ body: { result: 'Called API version 2' } }); - } - ); + router.versioned + .get({ + path: DEPRECATED_ROUTES.VERSIONED_INTERNAL_ROUTE, + description: 'Routing example plugin deprecated versioned route.', + access: 'internal', + options: { + excludeFromOAS: true, + }, + enableQueryVersion: true, + }) + .addVersion( + { + options: { + deprecated: { + documentationUrl: 'https://elastic.co/', + severity: 'warning', + reason: { type: 'bump', newApiVersion: '2' }, + }, + }, + validate: false, + version: '1', + }, + (ctx, req, res) => { + return res.ok({ + body: { result: 'Called internal deprecated version of the API 1.' }, + }); + } + ) + .addVersion( + { + validate: false, + version: '2', + }, + (ctx, req, res) => { + return res.ok({ + body: { result: 'Called non-deprecated version of the API.' }, + }); + } + ); }; diff --git a/examples/routing_example/server/routes/message_routes.ts b/examples/routing_example/server/routes/message_routes.ts index c4f4aea1cf3e3..ccf200e811ffa 100644 --- a/examples/routing_example/server/routes/message_routes.ts +++ b/examples/routing_example/server/routes/message_routes.ts @@ -63,6 +63,9 @@ export function registerGetMessageByIdRoute(router: IRouter) { router.get( { path: `${INTERNAL_GET_MESSAGE_BY_ID_ROUTE}/{id}`, + options: { + access: 'internal', + }, validate: { params: schema.object({ id: schema.string(), diff --git a/packages/core/deprecations/core-deprecations-common/index.ts b/packages/core/deprecations/core-deprecations-common/index.ts index 005e84d7d57f1..de8122a18c551 100644 --- a/packages/core/deprecations/core-deprecations-common/index.ts +++ b/packages/core/deprecations/core-deprecations-common/index.ts @@ -11,6 +11,7 @@ export type { BaseDeprecationDetails, ConfigDeprecationDetails, FeatureDeprecationDetails, + ApiDeprecationDetails, DeprecationsDetails, DomainDeprecationDetails, DeprecationsGetResponse, diff --git a/packages/core/deprecations/core-deprecations-common/src/types.ts b/packages/core/deprecations/core-deprecations-common/src/types.ts index 85da30b2c1287..9a08be7808452 100644 --- a/packages/core/deprecations/core-deprecations-common/src/types.ts +++ b/packages/core/deprecations/core-deprecations-common/src/types.ts @@ -121,7 +121,7 @@ export type DeprecationsDetails = /** * @public */ -export type DomainDeprecationDetails = DeprecationsDetails & { +export type DomainDeprecationDetails = ExtendedDetails & { domainId: string; }; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.ts deleted file mode 100644 index 45893987ddf92..0000000000000 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import type { InternalHttpServiceSetup } from '@kbn/core-http-server-internal'; -import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal'; -import type { RouterDeprecatedRouteDetails } from '@kbn/core-http-server'; -import { DeprecationsDetails } from '@kbn/core-deprecations-common'; -import type { DeprecationsFactory } from '../deprecations_factory'; -import { - getApiDeprecationMessage, - getApiDeprecationsManualSteps, - getApiDeprecationTitle, -} from './i18n_texts'; - -interface ApiDeprecationsServiceDeps { - deprecationsFactory: DeprecationsFactory; - http: InternalHttpServiceSetup; - coreUsageData: InternalCoreUsageDataSetup; -} - -export const buildApiDeprecationId = ({ - routePath, - routeMethod, - routeVersion, -}: Pick): string => { - return [ - routeVersion || 'unversioned', - routeMethod.toLocaleLowerCase(), - routePath.replace(/\/$/, ''), - ].join('|'); -}; - -export const createGetApiDeprecations = - ({ http, coreUsageData }: Pick) => - async (): Promise => { - const deprecatedRoutes = http.getRegisteredDeprecatedApis(); - const usageClient = coreUsageData.getClient(); - const deprecatedApiUsageStats = await usageClient.getDeprecatedApiUsageStats(); - - return deprecatedApiUsageStats - .filter(({ apiTotalCalls, totalMarkedAsResolved }) => { - return apiTotalCalls > totalMarkedAsResolved; - }) - .filter(({ apiId }) => - deprecatedRoutes.some((routeDetails) => buildApiDeprecationId(routeDetails) === apiId) - ) - .map((apiUsageStats) => { - const { apiId, apiTotalCalls, totalMarkedAsResolved } = apiUsageStats; - const routeDeprecationDetails = deprecatedRoutes.find( - (routeDetails) => buildApiDeprecationId(routeDetails) === apiId - )!; - const { routeVersion, routePath, routeDeprecationOptions, routeMethod } = - routeDeprecationDetails; - - const deprecationLevel = routeDeprecationOptions.severity || 'warning'; - - return { - apiId, - title: getApiDeprecationTitle(routeDeprecationDetails), - level: deprecationLevel, - message: getApiDeprecationMessage(routeDeprecationDetails, apiUsageStats), - documentationUrl: routeDeprecationOptions.documentationUrl, - correctiveActions: { - manualSteps: getApiDeprecationsManualSteps(routeDeprecationDetails), - mark_as_resolved_api: { - routePath, - routeMethod, - routeVersion, - apiTotalCalls, - totalMarkedAsResolved, - timestamp: new Date(), - }, - }, - deprecationType: 'api', - domainId: 'core.routes-deprecations', - }; - }); - }; - -export const registerApiDeprecationsInfo = ({ - deprecationsFactory, - http, - coreUsageData, -}: ApiDeprecationsServiceDeps): void => { - const deprecationsRegistery = deprecationsFactory.getRegistry('core.api_deprecations'); - - deprecationsRegistery.registerDeprecations({ - getDeprecations: createGetApiDeprecations({ http, coreUsageData }), - }); -}; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/access_deprecations.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/access_deprecations.ts new file mode 100644 index 0000000000000..2a0c2a8cae5ff --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/access_deprecations.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import type { + ApiDeprecationDetails, + DomainDeprecationDetails, +} from '@kbn/core-deprecations-common'; + +import type { PostValidationMetadata } from '@kbn/core-http-server'; +import type { BuildApiDeprecationDetailsParams } from '../types'; +import { + getApiDeprecationMessage, + getApiDeprecationsManualSteps, + getApiDeprecationTitle, +} from './i18n_texts'; + +export const getIsAccessApiDeprecation = ({ + isInternalApiRequest, + isPublicAccess, +}: PostValidationMetadata): boolean => { + const isNotPublicAccess = !isPublicAccess; + const isNotInternalRequest = !isInternalApiRequest; + + return !!(isNotPublicAccess && isNotInternalRequest); +}; + +export const buildApiAccessDeprecationDetails = ({ + apiUsageStats, + deprecatedApiDetails, +}: BuildApiDeprecationDetailsParams): DomainDeprecationDetails => { + const { apiId, apiTotalCalls, totalMarkedAsResolved } = apiUsageStats; + const { routeVersion, routePath, routeDeprecationOptions, routeMethod } = deprecatedApiDetails; + + const deprecationLevel = routeDeprecationOptions?.severity || 'warning'; + + return { + apiId, + title: getApiDeprecationTitle(deprecatedApiDetails), + level: deprecationLevel, + message: getApiDeprecationMessage(deprecatedApiDetails, apiUsageStats), + documentationUrl: routeDeprecationOptions?.documentationUrl, + correctiveActions: { + manualSteps: getApiDeprecationsManualSteps(), + mark_as_resolved_api: { + routePath, + routeMethod, + routeVersion, + apiTotalCalls, + totalMarkedAsResolved, + timestamp: new Date(), + }, + }, + deprecationType: 'api', + domainId: 'core.http.access-deprecations', + }; +}; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/i18n_texts.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/i18n_texts.ts new file mode 100644 index 0000000000000..bd1f92cf368fe --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/i18n_texts.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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { RouterDeprecatedApiDetails } from '@kbn/core-http-server'; +import { CoreDeprecatedApiUsageStats } from '@kbn/core-usage-data-server'; +import { i18n } from '@kbn/i18n'; +import moment from 'moment'; + +export const getApiDeprecationTitle = ( + details: Pick +) => { + const { routePath, routeMethod } = details; + const routeWithMethod = `${routeMethod.toUpperCase()} ${routePath}`; + + return i18n.translate('core.deprecations.apiAccessDeprecation.infoTitle', { + defaultMessage: 'The "{routeWithMethod}" API is internal to Elastic', + values: { + routeWithMethod, + }, + }); +}; + +export const getApiDeprecationMessage = ( + details: Pick< + RouterDeprecatedApiDetails, + 'routePath' | 'routeMethod' | 'routeDeprecationOptions' + >, + apiUsageStats: CoreDeprecatedApiUsageStats +): string[] => { + const { routePath, routeMethod, routeDeprecationOptions } = details; + const { apiLastCalledAt, apiTotalCalls, markedAsResolvedLastCalledAt, totalMarkedAsResolved } = + apiUsageStats; + + const diff = apiTotalCalls - totalMarkedAsResolved; + const wasResolvedBefore = totalMarkedAsResolved > 0; + const routeWithMethod = `${routeMethod.toUpperCase()} ${routePath}`; + + const messages = [ + i18n.translate('core.deprecations.apiAccessDeprecation.apiCallsDetailsMessage', { + defaultMessage: + 'The API "{routeWithMethod}" has been called {apiTotalCalls} times. The last call was on {apiLastCalledAt}.', + values: { + routeWithMethod, + apiTotalCalls, + apiLastCalledAt: moment(apiLastCalledAt).format('LLLL Z'), + }, + }), + ]; + + if (wasResolvedBefore) { + messages.push( + i18n.translate('core.deprecations.apiAccessDeprecation.previouslyMarkedAsResolvedMessage', { + defaultMessage: + 'This issue has been marked as resolved on {markedAsResolvedLastCalledAt} but the API has been called {timeSinceLastResolved, plural, one {# time} other {# times}} since.', + values: { + timeSinceLastResolved: diff, + markedAsResolvedLastCalledAt: moment(markedAsResolvedLastCalledAt).format('LLLL Z'), + }, + }) + ); + } + + messages.push( + i18n.translate('core.deprecations.apiAccessDeprecation.internalApiExplanationMessage', { + defaultMessage: + 'Internal APIs are meant to be used by Elastic services only. You should not use them. External access to these APIs will be restricted.', + }) + ); + + if (routeDeprecationOptions?.message) { + // Surfaces additional deprecation messages passed into the route in UA + messages.push(routeDeprecationOptions.message); + } + + return messages; +}; + +export const getApiDeprecationsManualSteps = (): string[] => { + return [ + i18n.translate('core.deprecations.apiAccessDeprecation.manualSteps.identifyCallsOriginStep', { + defaultMessage: 'Identify the origin of these API calls.', + }), + i18n.translate('core.deprecations.apiAccessDeprecation.manualSteps.deleteRequestsStep', { + defaultMessage: + 'Delete any requests you have that use this API. Check the learn more link for possible alternatives.', + }), + i18n.translate( + 'core.deprecations.apiAccessDeprecation.manualSteps.accessDepractionMarkAsResolvedStep', + { + defaultMessage: + 'Once you have successfully stopped using this API, mark this issue as resolved. It will no longer appear in the Upgrade Assistant unless another call using this API is detected.', + } + ), + ]; +}; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/index.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/index.ts new file mode 100644 index 0000000000000..b78ddba35d2c2 --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/access/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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export { buildApiAccessDeprecationDetails, getIsAccessApiDeprecation } from './access_deprecations'; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/api_deprecation_id.test.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/api_deprecation_id.test.ts new file mode 100644 index 0000000000000..151b7bd8d4cec --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/api_deprecation_id.test.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { buildApiDeprecationId } from './api_deprecation_id'; + +describe('#buildApiDeprecationId', () => { + it('returns apiDeprecationId string for versioned routes', () => { + const apiDeprecationId = buildApiDeprecationId({ + routeMethod: 'get', + routePath: '/api/test', + routeVersion: '10-10-2023', + }); + expect(apiDeprecationId).toBe('10-10-2023|get|/api/test'); + }); + + it('returns apiDeprecationId string for unversioned routes', () => { + const apiDeprecationId = buildApiDeprecationId({ + routeMethod: 'get', + routePath: '/api/test', + }); + expect(apiDeprecationId).toBe('unversioned|get|/api/test'); + }); + + it('gives the same ID the route method is capitalized or not', () => { + const apiDeprecationId = buildApiDeprecationId({ + // @ts-expect-error + routeMethod: 'GeT', + routePath: '/api/test', + routeVersion: '10-10-2023', + }); + + expect(apiDeprecationId).toBe('10-10-2023|get|/api/test'); + }); + + it('gives the same ID the route path has a trailing slash or not', () => { + const apiDeprecationId = buildApiDeprecationId({ + // @ts-expect-error + routeMethod: 'GeT', + routePath: '/api/test/', + routeVersion: '10-10-2023', + }); + + expect(apiDeprecationId).toBe('10-10-2023|get|/api/test'); + }); +}); diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/api_deprecation_id.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/api_deprecation_id.ts new file mode 100644 index 0000000000000..0e3b6107a25e5 --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/api_deprecation_id.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { RouterDeprecatedApiDetails } from '@kbn/core-http-server'; + +export const buildApiDeprecationId = ({ + routePath, + routeMethod, + routeVersion, +}: Pick): string => { + return [ + routeVersion || 'unversioned', + routeMethod.toLocaleLowerCase(), + routePath.replace(/\/$/, ''), + ].join('|'); +}; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/index.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/index.ts new file mode 100644 index 0000000000000..8d823e8ad2118 --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/index.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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export { registerApiDeprecationsInfo } from './register_api_depercation_info'; +export { getIsAccessApiDeprecation } from './access'; +export { getIsRouteApiDeprecation } from './route'; +export { buildApiDeprecationId } from './api_deprecation_id'; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/register_api_depercation_info.test.ts similarity index 89% rename from packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts rename to packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/register_api_depercation_info.test.ts index 5f9d0bfbb4b84..9a7842d8915db 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations.test.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/register_api_depercation_info.test.ts @@ -8,13 +8,13 @@ */ import type { DeepPartial } from '@kbn/utility-types'; -import { mockDeprecationsRegistry, mockDeprecationsFactory } from '../mocks'; +import { mockDeprecationsRegistry, mockDeprecationsFactory } from '../../mocks'; import { registerApiDeprecationsInfo, - buildApiDeprecationId, createGetApiDeprecations, -} from './api_deprecations'; -import { RouterDeprecatedRouteDetails } from '@kbn/core-http-server'; +} from './register_api_depercation_info'; +import { buildApiDeprecationId } from './api_deprecation_id'; +import { RouterDeprecatedApiDetails } from '@kbn/core-http-server'; import { httpServiceMock } from '@kbn/core-http-server-mocks'; import { coreUsageDataServiceMock, @@ -58,10 +58,11 @@ describe('#registerApiDeprecationsInfo', () => { describe('#createGetApiDeprecations', () => { const createDeprecatedRouteDetails = ( - overrides?: DeepPartial - ): RouterDeprecatedRouteDetails => + overrides?: DeepPartial + ): RouterDeprecatedApiDetails => _.merge( { + routeAccess: 'public', routeDeprecationOptions: { documentationUrl: 'https://fake-url', severity: 'critical', @@ -72,7 +73,7 @@ describe('#registerApiDeprecationsInfo', () => { routeMethod: 'get', routePath: '/api/test/', routeVersion: '123', - } as RouterDeprecatedRouteDetails, + } as RouterDeprecatedApiDetails, overrides ); @@ -124,7 +125,7 @@ describe('#registerApiDeprecationsInfo', () => { }, "deprecationType": "api", "documentationUrl": "https://fake-url", - "domainId": "core.routes-deprecations", + "domainId": "core.http.routes-deprecations", "level": "critical", "message": Array [ "The API \\"GET /api/test_removed/\\" has been called 13 times. The last call was on Sunday, September 1, 2024 6:06 AM -04:00.", @@ -171,7 +172,7 @@ describe('#registerApiDeprecationsInfo', () => { }, "deprecationType": "api", "documentationUrl": "https://fake-url", - "domainId": "core.routes-deprecations", + "domainId": "core.http.routes-deprecations", "level": "critical", "message": Array [ "The API \\"GET /api/test_migrated/\\" has been called 13 times. The last call was on Sunday, September 1, 2024 6:06 AM -04:00.", @@ -216,7 +217,7 @@ describe('#registerApiDeprecationsInfo', () => { }, "deprecationType": "api", "documentationUrl": "https://fake-url", - "domainId": "core.routes-deprecations", + "domainId": "core.http.routes-deprecations", "level": "critical", "message": Array [ "The API \\"GET /api/test_bumped/\\" has been called 13 times. The last call was on Sunday, September 1, 2024 6:06 AM -04:00.", @@ -260,7 +261,7 @@ describe('#registerApiDeprecationsInfo', () => { }, "deprecationType": "api", "documentationUrl": "https://fake-url", - "domainId": "core.routes-deprecations", + "domainId": "core.http.routes-deprecations", "level": "critical", "message": Array [ "The API \\"GET /api/test_deprecated/\\" has been called 13 times. The last call was on Sunday, September 1, 2024 6:06 AM -04:00.", @@ -323,7 +324,7 @@ describe('#registerApiDeprecationsInfo', () => { }, "deprecationType": "api", "documentationUrl": "https://fake-url", - "domainId": "core.routes-deprecations", + "domainId": "core.http.routes-deprecations", "level": "critical", "message": Array [ "The API \\"GET /api/test_never_resolved/\\" has been called 13 times. The last call was on Sunday, September 1, 2024 6:06 AM -04:00.", @@ -355,44 +356,3 @@ describe('#registerApiDeprecationsInfo', () => { }); }); }); - -describe('#buildApiDeprecationId', () => { - it('returns apiDeprecationId string for versioned routes', () => { - const apiDeprecationId = buildApiDeprecationId({ - routeMethod: 'get', - routePath: '/api/test', - routeVersion: '10-10-2023', - }); - expect(apiDeprecationId).toBe('10-10-2023|get|/api/test'); - }); - - it('returns apiDeprecationId string for unversioned routes', () => { - const apiDeprecationId = buildApiDeprecationId({ - routeMethod: 'get', - routePath: '/api/test', - }); - expect(apiDeprecationId).toBe('unversioned|get|/api/test'); - }); - - it('gives the same ID the route method is capitalized or not', () => { - const apiDeprecationId = buildApiDeprecationId({ - // @ts-expect-error - routeMethod: 'GeT', - routePath: '/api/test', - routeVersion: '10-10-2023', - }); - - expect(apiDeprecationId).toBe('10-10-2023|get|/api/test'); - }); - - it('gives the same ID the route path has a trailing slash or not', () => { - const apiDeprecationId = buildApiDeprecationId({ - // @ts-expect-error - routeMethod: 'GeT', - routePath: '/api/test/', - routeVersion: '10-10-2023', - }); - - expect(apiDeprecationId).toBe('10-10-2023|get|/api/test'); - }); -}); diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/register_api_depercation_info.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/register_api_depercation_info.ts new file mode 100644 index 0000000000000..f4c9847b09e54 --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/register_api_depercation_info.ts @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { DeprecationsDetails } from '@kbn/core-deprecations-common'; + +import { buildApiRouteDeprecationDetails } from './route/route_deprecations'; +import { buildApiAccessDeprecationDetails } from './access/access_deprecations'; +import { buildApiDeprecationId } from './api_deprecation_id'; +import type { ApiDeprecationsServiceDeps } from './types'; + +export const createGetApiDeprecations = + ({ http, coreUsageData }: Pick) => + async (): Promise => { + const usageClient = coreUsageData.getClient(); + const deprecatedApis = http.getRegisteredDeprecatedApis(); + const deprecatedApiUsageStats = await usageClient.getDeprecatedApiUsageStats(); + + return deprecatedApiUsageStats + .filter(({ apiTotalCalls, totalMarkedAsResolved }) => { + return apiTotalCalls > totalMarkedAsResolved; + }) + .filter(({ apiId }) => + deprecatedApis.some((routeDetails) => buildApiDeprecationId(routeDetails) === apiId) + ) + .map((apiUsageStats) => { + const { apiId } = apiUsageStats; + const deprecatedApiDetails = deprecatedApis.find( + (routeDetails) => buildApiDeprecationId(routeDetails) === apiId + ); + if (!deprecatedApiDetails) { + throw new Error(`Unable to find deprecation details for "${apiId}"`); + } + + const { routeAccess } = deprecatedApiDetails; + switch (routeAccess) { + case 'public': { + return buildApiRouteDeprecationDetails({ + apiUsageStats, + deprecatedApiDetails, + }); + } + // if no access is specified then internal is the default + case 'internal': + default: { + return buildApiAccessDeprecationDetails({ + apiUsageStats, + deprecatedApiDetails, + }); + } + } + }); + }; + +export const registerApiDeprecationsInfo = ({ + deprecationsFactory, + http, + coreUsageData, +}: ApiDeprecationsServiceDeps): void => { + const deprecationsRegistery = deprecationsFactory.getRegistry('core.api_deprecations'); + + deprecationsRegistery.registerDeprecations({ + getDeprecations: createGetApiDeprecations({ http, coreUsageData }), + }); +}; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/i18n_texts.ts similarity index 67% rename from packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts rename to packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/i18n_texts.ts index e52dd1f3d8fd1..8cbade658bb2e 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/i18n_texts.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/i18n_texts.ts @@ -7,22 +7,26 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { RouterDeprecatedRouteDetails } from '@kbn/core-http-server'; +import { RouterDeprecatedApiDetails } from '@kbn/core-http-server'; import { CoreDeprecatedApiUsageStats } from '@kbn/core-usage-data-server'; import { i18n } from '@kbn/i18n'; import moment from 'moment'; -export const getApiDeprecationTitle = (details: RouterDeprecatedRouteDetails) => { +export const getApiDeprecationTitle = (details: RouterDeprecatedApiDetails) => { const { routePath, routeMethod, routeDeprecationOptions } = details; + if (!routeDeprecationOptions) { + throw new Error(`Router "deprecated" param is missing for path "${routePath}".`); + } + const deprecationType = routeDeprecationOptions.reason.type; const routeWithMethod = `${routeMethod.toUpperCase()} ${routePath}`; - const deprecationTypeText = i18n.translate('core.deprecations.deprecations.apiDeprecationType', { + const deprecationTypeText = i18n.translate('core.deprecations.apiRouteDeprecation.type', { defaultMessage: '{deprecationType, select, remove {is removed} bump {has a newer version available} migrate {is migrated to a different API} other {is deprecated}}', values: { deprecationType }, }); - return i18n.translate('core.deprecations.deprecations.apiDeprecationInfoTitle', { + return i18n.translate('core.deprecations.apiRouteDeprecation.infoTitle', { defaultMessage: 'The "{routeWithMethod}" route {deprecationTypeText}', values: { routeWithMethod, @@ -32,10 +36,13 @@ export const getApiDeprecationTitle = (details: RouterDeprecatedRouteDetails) => }; export const getApiDeprecationMessage = ( - details: RouterDeprecatedRouteDetails, + details: RouterDeprecatedApiDetails, apiUsageStats: CoreDeprecatedApiUsageStats ): string[] => { const { routePath, routeMethod, routeDeprecationOptions } = details; + if (!routeDeprecationOptions) { + throw new Error(`Router "deprecated" param is missing for path "${routePath}".`); + } const { apiLastCalledAt, apiTotalCalls, markedAsResolvedLastCalledAt, totalMarkedAsResolved } = apiUsageStats; @@ -44,7 +51,7 @@ export const getApiDeprecationMessage = ( const routeWithMethod = `${routeMethod.toUpperCase()} ${routePath}`; const messages = [ - i18n.translate('core.deprecations.deprecations.apiDeprecationApiCallsDetailsMessage', { + i18n.translate('core.deprecations.apiRouteDeprecation.apiCallsDetailsMessage', { defaultMessage: 'The API "{routeWithMethod}" has been called {apiTotalCalls} times. The last call was on {apiLastCalledAt}.', values: { @@ -57,17 +64,14 @@ export const getApiDeprecationMessage = ( if (wasResolvedBefore) { messages.push( - i18n.translate( - 'core.deprecations.deprecations.apiDeprecationPreviouslyMarkedAsResolvedMessage', - { - defaultMessage: - 'This issue has been marked as resolved on {markedAsResolvedLastCalledAt} but the API has been called {timeSinceLastResolved, plural, one {# time} other {# times}} since.', - values: { - timeSinceLastResolved: diff, - markedAsResolvedLastCalledAt: moment(markedAsResolvedLastCalledAt).format('LLLL Z'), - }, - } - ) + i18n.translate('core.deprecations.apiRouteDeprecation.previouslyMarkedAsResolvedMessage', { + defaultMessage: + 'This issue has been marked as resolved on {markedAsResolvedLastCalledAt} but the API has been called {timeSinceLastResolved, plural, one {# time} other {# times}} since.', + values: { + timeSinceLastResolved: diff, + markedAsResolvedLastCalledAt: moment(markedAsResolvedLastCalledAt).format('LLLL Z'), + }, + }) ); } @@ -79,12 +83,16 @@ export const getApiDeprecationMessage = ( return messages; }; -export const getApiDeprecationsManualSteps = (details: RouterDeprecatedRouteDetails): string[] => { - const { routeDeprecationOptions } = details; +export const getApiDeprecationsManualSteps = (details: RouterDeprecatedApiDetails): string[] => { + const { routePath, routeDeprecationOptions } = details; + if (!routeDeprecationOptions) { + throw new Error(`Router "deprecated" param is missing for path "${routePath}".`); + } + const deprecationType = routeDeprecationOptions.reason.type; const manualSteps = [ - i18n.translate('core.deprecations.deprecations.manualSteps.apiIseprecatedStep', { + i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.identifyCallsOriginStep', { defaultMessage: 'Identify the origin of these API calls.', }), ]; @@ -93,7 +101,7 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedRouteDeta case 'bump': { const { newApiVersion } = routeDeprecationOptions.reason; manualSteps.push( - i18n.translate('core.deprecations.deprecations.manualSteps.bumpDetailsStep', { + i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.bumpTypeStep', { defaultMessage: 'Update the requests to use the following new version of the API instead: "{newApiVersion}".', values: { newApiVersion }, @@ -104,7 +112,7 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedRouteDeta case 'remove': { manualSteps.push( - i18n.translate('core.deprecations.deprecations.manualSteps.removeTypeExplainationStep', { + i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.removeTypeStep', { defaultMessage: 'This API no longer exists and no replacement is available. Delete any requests you have that use this API.', }) @@ -113,7 +121,7 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedRouteDeta } case 'deprecate': { manualSteps.push( - i18n.translate('core.deprecations.deprecations.manualSteps.removeTypeExplainationStep', { + i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.deprecateTypeStep', { defaultMessage: 'For now, the API will still work, but will be moved or removed in a future version. Check the Learn more link for more information. If you are no longer using the API, you can mark this issue as resolved. It will no longer appear in the Upgrade Assistant unless another call using this API is detected.', }) @@ -125,7 +133,7 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedRouteDeta const newRouteWithMethod = `${newApiMethod.toUpperCase()} ${newApiPath}`; manualSteps.push( - i18n.translate('core.deprecations.deprecations.manualSteps.migrateDetailsStep', { + i18n.translate('core.deprecations.apiRouteDeprecation.manualSteps.migrateTypeStep', { defaultMessage: 'Update the requests to use the following new API instead: "{newRouteWithMethod}".', values: { newRouteWithMethod }, @@ -137,10 +145,13 @@ export const getApiDeprecationsManualSteps = (details: RouterDeprecatedRouteDeta if (deprecationType !== 'deprecate') { manualSteps.push( - i18n.translate('core.deprecations.deprecations.manualSteps.markAsResolvedStep', { - defaultMessage: - 'Check that you are no longer using the old API in any requests, and mark this issue as resolved. It will no longer appear in the Upgrade Assistant unless another call using this API is detected.', - }) + i18n.translate( + 'core.deprecations.apiRouteDeprecation.manualSteps.routeDepractionMarkAsResolvedStep', + { + defaultMessage: + 'Check that you are no longer using the old API in any requests, and mark this issue as resolved. It will no longer appear in the Upgrade Assistant unless another call using this API is detected.', + } + ) ); } diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/index.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/index.ts new file mode 100644 index 0000000000000..9caf06c7def8f --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export { buildApiRouteDeprecationDetails, getIsRouteApiDeprecation } from './route_deprecations'; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/route_deprecations.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/route_deprecations.ts new file mode 100644 index 0000000000000..6f9bab78dff9f --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/route/route_deprecations.ts @@ -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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import type { + ApiDeprecationDetails, + DomainDeprecationDetails, +} from '@kbn/core-deprecations-common'; +import _ from 'lodash'; +import type { PostValidationMetadata } from '@kbn/core-http-server'; +import { + getApiDeprecationMessage, + getApiDeprecationsManualSteps, + getApiDeprecationTitle, +} from './i18n_texts'; +import type { BuildApiDeprecationDetailsParams } from '../types'; + +export const getIsRouteApiDeprecation = ({ + isInternalApiRequest, + deprecated, +}: PostValidationMetadata): boolean => { + const hasDeprecatedObject = deprecated && _.isObject(deprecated); + const isNotInternalRequest = !isInternalApiRequest; + + return !!(hasDeprecatedObject && isNotInternalRequest); +}; + +export const buildApiRouteDeprecationDetails = ({ + apiUsageStats, + deprecatedApiDetails, +}: BuildApiDeprecationDetailsParams): DomainDeprecationDetails => { + const { apiId, apiTotalCalls, totalMarkedAsResolved } = apiUsageStats; + const { routeVersion, routePath, routeDeprecationOptions, routeMethod } = deprecatedApiDetails; + if (!routeDeprecationOptions) { + throw new Error(`Expecing deprecated to be defined for route ${apiId}`); + } + + const deprecationLevel = routeDeprecationOptions.severity || 'warning'; + + return { + apiId, + title: getApiDeprecationTitle(deprecatedApiDetails), + level: deprecationLevel, + message: getApiDeprecationMessage(deprecatedApiDetails, apiUsageStats), + documentationUrl: routeDeprecationOptions.documentationUrl, + correctiveActions: { + manualSteps: getApiDeprecationsManualSteps(deprecatedApiDetails), + mark_as_resolved_api: { + routePath, + routeMethod, + routeVersion, + apiTotalCalls, + totalMarkedAsResolved, + timestamp: new Date(), + }, + }, + deprecationType: 'api', + domainId: 'core.http.routes-deprecations', + }; +}; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/types.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/types.ts new file mode 100644 index 0000000000000..ad6436b70c55f --- /dev/null +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/api_deprecations/types.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import type { InternalHttpServiceSetup } from '@kbn/core-http-server-internal'; +import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal'; +import type { RouterDeprecatedApiDetails } from '@kbn/core-http-server'; +import type { CoreDeprecatedApiUsageStats } from '@kbn/core-usage-data-server'; +import type { DeprecationsFactory } from '../../deprecations_factory'; + +export interface ApiDeprecationsServiceDeps { + deprecationsFactory: DeprecationsFactory; + http: InternalHttpServiceSetup; + coreUsageData: InternalCoreUsageDataSetup; +} + +export interface BuildApiDeprecationDetailsParams { + apiUsageStats: CoreDeprecatedApiUsageStats; + deprecatedApiDetails: RouterDeprecatedApiDetails; +} diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/index.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/index.ts index aecf3d5b299a2..21e4f801ca987 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/index.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations/index.ts @@ -7,5 +7,10 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -export { buildApiDeprecationId, registerApiDeprecationsInfo } from './api_deprecations'; +export { + buildApiDeprecationId, + registerApiDeprecationsInfo, + getIsAccessApiDeprecation, + getIsRouteApiDeprecation, +} from './api_deprecations'; export { registerConfigDeprecationsInfo } from './config_deprecations'; diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations_service.test.ts b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations_service.test.ts index 39c299d980531..0ea283b6eb5d6 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/deprecations_service.test.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/deprecations_service.test.ts @@ -52,7 +52,10 @@ describe('DeprecationsService', () => { expect(http.createRouter).toBeCalledWith('/api/deprecations'); // registers get route '/' expect(router.get).toHaveBeenCalledTimes(1); - expect(router.get).toHaveBeenCalledWith({ path: '/', validate: false }, expect.any(Function)); + expect(router.get).toHaveBeenCalledWith( + { options: { access: 'public' }, path: '/', validate: false }, + expect.any(Function) + ); }); it('calls registerConfigDeprecationsInfo', async () => { diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/routes/get.ts b/packages/core/deprecations/core-deprecations-server-internal/src/routes/get.ts index ed3cd061b633b..42a2af4ff7d1d 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/routes/get.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/routes/get.ts @@ -14,6 +14,9 @@ export const registerGetRoute = (router: InternalDeprecationRouter) => { router.get( { path: '/', + options: { + access: 'public', + }, validate: false, }, async (context, req, res) => { diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/routes/post_validation_handler.ts b/packages/core/deprecations/core-deprecations-server-internal/src/routes/post_validation_handler.ts index 6719f8b99ff50..20f680d4c313d 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/routes/post_validation_handler.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/routes/post_validation_handler.ts @@ -10,9 +10,9 @@ import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-server-internal'; import type { CoreKibanaRequest } from '@kbn/core-http-router-server-internal'; import type { InternalHttpServiceSetup } from '@kbn/core-http-server-internal'; -import { isObject } from 'lodash'; -import { RouteDeprecationInfo } from '@kbn/core-http-server/src/router/route'; // shouldn't use deep imports +import type { PostValidationMetadata } from '@kbn/core-http-server'; import { buildApiDeprecationId } from '../deprecations'; +import { getIsRouteApiDeprecation, getIsAccessApiDeprecation } from '../deprecations'; interface Dependencies { coreUsageData: InternalCoreUsageDataSetup; @@ -35,8 +35,11 @@ export function createRouteDeprecationsHandler({ }: { coreUsageData: InternalCoreUsageDataSetup; }) { - return (req: CoreKibanaRequest, { deprecated }: { deprecated?: RouteDeprecationInfo }) => { - if (deprecated && isObject(deprecated) && req.route.routePath) { + return (req: CoreKibanaRequest, metadata: PostValidationMetadata) => { + const hasRouteDeprecation = getIsRouteApiDeprecation(metadata); + const hasAccessDeprecation = getIsAccessApiDeprecation(metadata); + const isApiDeprecation = hasAccessDeprecation || hasRouteDeprecation; + if (isApiDeprecation && req.route.routePath) { const counterName = buildApiDeprecationId({ routeMethod: req.route.method, routePath: req.route.routePath, diff --git a/packages/core/deprecations/core-deprecations-server-internal/src/routes/resolve_deprecated_api.ts b/packages/core/deprecations/core-deprecations-server-internal/src/routes/resolve_deprecated_api.ts index 840bc5ac22d23..14939188ef0fb 100644 --- a/packages/core/deprecations/core-deprecations-server-internal/src/routes/resolve_deprecated_api.ts +++ b/packages/core/deprecations/core-deprecations-server-internal/src/routes/resolve_deprecated_api.ts @@ -19,6 +19,9 @@ export const registerMarkAsResolvedRoute = ( router.post( { path: '/mark_as_resolved', + options: { + access: 'internal', + }, validate: { body: schema.object({ domainId: schema.string(), 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 9f89f1a70bb47..cbccf31fc0946 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 @@ -177,9 +177,14 @@ export class CoreKibanaRequest< this.headers = isRealReq ? deepFreeze({ ...request.headers }) : request.headers; this.isSystemRequest = this.headers['kbn-system-request'] === 'true'; this.isFakeRequest = !isRealReq; + // set to false if elasticInternalOrigin is explicitly set to false + // otherwise check for the header or the query param this.isInternalApiRequest = - X_ELASTIC_INTERNAL_ORIGIN_REQUEST in this.headers || - Boolean(this.url?.searchParams?.has(ELASTIC_INTERNAL_ORIGIN_QUERY_PARAM)); + this.url?.searchParams?.get(ELASTIC_INTERNAL_ORIGIN_QUERY_PARAM) === 'false' + ? false + : X_ELASTIC_INTERNAL_ORIGIN_REQUEST in this.headers || + this.url?.searchParams?.has(ELASTIC_INTERNAL_ORIGIN_QUERY_PARAM); + // prevent Symbol exposure via Object.getOwnPropertySymbols() Object.defineProperty(this, requestSymbol, { value: request, 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 e7ad85fcda33a..c2ea09605c4e0 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 @@ -28,12 +28,12 @@ import type { VersionedRouter, RouteRegistrar, RouteSecurity, + PostValidationMetadata, } from '@kbn/core-http-server'; import { isZod } from '@kbn/zod'; import { validBodyOutput, getRequestValidation } from '@kbn/core-http-server'; import type { RouteSecurityGetter } from '@kbn/core-http-server'; import type { DeepPartial } from '@kbn/utility-types'; -import { RouteDeprecationInfo } from '@kbn/core-http-server/src/router/route'; import { RouteValidator } from './validator'; import { ALLOWED_PUBLIC_VERSION, CoreVersionedRouter } from './versioned_router'; import { CoreKibanaRequest } from './request'; @@ -287,10 +287,13 @@ export class Router { const postValidate: RouterEvents = 'onPostValidate'; - Router.ee.emit(postValidate, request, routeOptions); + Router.ee.emit(postValidate, request, postValidateConext); }; private async handle({ @@ -304,7 +307,7 @@ export class Router void; + onPostValidation: (req: KibanaRequest, metadata: PostValidationMetadata) => void; }; isPublicUnversionedRoute: boolean; handler: RequestHandlerEnhanced< @@ -337,11 +340,19 @@ export class Router { + const access = route.options.access; if (route.isVersioned === true) { return [...route.handlers.entries()].map(([_, { options }]) => { const deprecated = options.options?.deprecated; - return { route, version: `${options.version}`, deprecated }; + return { route, version: `${options.version}`, deprecated, access }; }); } - return { route, version: undefined, deprecated: route.options.deprecated }; + + return { route, version: undefined, deprecated: route.options.deprecated, access }; }) .flat() - .filter(({ deprecated }) => isObject(deprecated)) - .flatMap(({ route, deprecated, version }) => { + .filter(({ deprecated, access }) => { + const isRouteDeprecation = isObject(deprecated); + const isAccessDeprecation = access === 'internal'; + return isRouteDeprecation || isAccessDeprecation; + }) + .flatMap(({ route, deprecated, version, access }) => { return { routeDeprecationOptions: deprecated!, routeMethod: route.method as RouteMethod, routePath: route.path, routeVersion: version, + routeAccess: access, }; }) ); 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 c81816470885e..28f8c70ebbb1e 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 @@ -417,6 +417,33 @@ describe('restrictInternal post-auth handler', () => { const request = createForgeRequest('public', { 'x-elastic-internal-origin': 'Kibana' }); createForwardSuccess(handler, request); }); + + it('overrides internal api when elasticInternalOrigin=false is set explicitly', () => { + const handler = createRestrictInternalRoutesPostAuthHandler( + { ...config, restrictInternalApis: true }, + logger + ); + + // Will be treated as external + const request = createForgeRequest( + 'internal', + { 'x-elastic-internal-origin': 'Kibana' }, + { elasticInternalOrigin: 'false' } + ); + + responseFactory.badRequest.mockReturnValue('badRequest' as any); + + const result = handler(request, responseFactory, toolkit); + + expect(toolkit.next).not.toHaveBeenCalled(); + expect(responseFactory.badRequest).toHaveBeenCalledTimes(1); + expect(responseFactory.badRequest.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "body": "uri [/internal/some-path] with method [get] exists but is not available with the current configuration", + } + `); + expect(result).toEqual('badRequest'); + }); }); describe('customHeaders pre-response handler', () => { diff --git a/packages/core/http/core-http-server-internal/src/types.ts b/packages/core/http/core-http-server-internal/src/types.ts index 0706af9ad73a2..c0443e5bc049c 100644 --- a/packages/core/http/core-http-server-internal/src/types.ts +++ b/packages/core/http/core-http-server-internal/src/types.ts @@ -16,10 +16,10 @@ import type { IContextContainer, HttpServiceSetup, HttpServiceStart, - RouterDeprecatedRouteDetails, + RouterDeprecatedApiDetails, } from '@kbn/core-http-server'; -import { CoreKibanaRequest } from '@kbn/core-http-router-server-internal'; -import { RouteDeprecationInfo } from '@kbn/core-http-server/src/router/route'; +import type { CoreKibanaRequest } from '@kbn/core-http-router-server-internal'; +import type { PostValidationMetadata } from '@kbn/core-http-server'; import type { HttpServerSetup } from './http_server'; import type { ExternalUrlConfig } from './external_url'; import type { InternalStaticAssets } from './static_assets'; @@ -58,7 +58,7 @@ export interface InternalHttpServiceSetup plugin?: PluginOpaqueId ) => IRouter; registerOnPostValidation( - cb: (req: CoreKibanaRequest, metadata: { deprecated: RouteDeprecationInfo }) => void + cb: (req: CoreKibanaRequest, metadata: PostValidationMetadata) => void ): void; registerRouterAfterListening: (router: IRouter) => void; registerStaticDir: (path: string, dirPath: string) => void; @@ -71,7 +71,7 @@ export interface InternalHttpServiceSetup contextName: ContextName, provider: IContextProvider ) => IContextContainer; - getRegisteredDeprecatedApis: () => RouterDeprecatedRouteDetails[]; + getRegisteredDeprecatedApis: () => RouterDeprecatedApiDetails[]; } /** @internal */ diff --git a/packages/core/http/core-http-server/index.ts b/packages/core/http/core-http-server/index.ts index d2c4cfb5c16f7..7b79dfe313bd6 100644 --- a/packages/core/http/core-http-server/index.ts +++ b/packages/core/http/core-http-server/index.ts @@ -93,7 +93,9 @@ export type { IRouter, RouteRegistrar, RouterRoute, - RouterDeprecatedRouteDetails, + RouterDeprecatedApiDetails, + RouterAccessDeprecatedApiDetails, + RouterRouteDeprecatedApiDetails, IKibanaSocket, KibanaErrorResponseFactory, KibanaRedirectionResponseFactory, @@ -121,6 +123,7 @@ export type { RouteSecurityGetter, InternalRouteSecurity, RouteDeprecationInfo, + PostValidationMetadata, } from './src/router'; export { validBodyOutput, diff --git a/packages/core/http/core-http-server/src/http_contract.ts b/packages/core/http/core-http-server/src/http_contract.ts index e2f675bd8d0c0..2da699e5ea4a6 100644 --- a/packages/core/http/core-http-server/src/http_contract.ts +++ b/packages/core/http/core-http-server/src/http_contract.ts @@ -12,7 +12,7 @@ import type { IContextProvider, IRouter, RequestHandlerContextBase, - RouterDeprecatedRouteDetails, + RouterDeprecatedApiDetails, } from './router'; import type { AuthenticationHandler, @@ -362,12 +362,12 @@ export interface HttpServiceSetup< getServerInfo: () => HttpServerInfo; /** - * Provides a list of all registered deprecated routes {{@link RouterDeprecatedRouteDetails | information}}. + * Provides a list of all registered deprecated routes {{@link RouterDeprecatedApiDetails | information}}. * The routers will be evaluated everytime this function gets called to * accommodate for any late route registrations - * @returns {RouterDeprecatedRouteDetails[]} + * @returns {RouterDeprecatedApiDetails[]} */ - getDeprecatedRoutes: () => RouterDeprecatedRouteDetails[]; + getDeprecatedRoutes: () => RouterDeprecatedApiDetails[]; } /** @public */ diff --git a/packages/core/http/core-http-server/src/router/index.ts b/packages/core/http/core-http-server/src/router/index.ts index 30a1b6a5c9cc1..166fcad324953 100644 --- a/packages/core/http/core-http-server/src/router/index.ts +++ b/packages/core/http/core-http-server/src/router/index.ts @@ -65,6 +65,7 @@ export type { Privilege, PrivilegeSet, RouteDeprecationInfo, + PostValidationMetadata, } from './route'; export { validBodyOutput, ReservedPrivilegesSet } from './route'; @@ -81,7 +82,14 @@ export type { LazyValidator, } from './route_validator'; export { RouteValidationError } from './route_validator'; -export type { IRouter, RouteRegistrar, RouterRoute, RouterDeprecatedRouteDetails } from './router'; +export type { + IRouter, + RouteRegistrar, + RouterRoute, + RouterDeprecatedApiDetails, + RouterAccessDeprecatedApiDetails, + RouterRouteDeprecatedApiDetails, +} from './router'; export type { IKibanaSocket } from './socket'; export type { KibanaErrorResponseFactory, 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 eec9a01f60562..da24adcb6802e 100644 --- a/packages/core/http/core-http-server/src/router/route.ts +++ b/packages/core/http/core-http-server/src/router/route.ts @@ -525,3 +525,12 @@ export interface RouteConfig { */ options?: RouteConfigOptions; } + +/** + * Post Validation Route emitter metadata. + */ +export interface PostValidationMetadata { + deprecated?: RouteDeprecationInfo; + isInternalApiRequest: boolean; + isPublicAccess: boolean; +} diff --git a/packages/core/http/core-http-server/src/router/router.ts b/packages/core/http/core-http-server/src/router/router.ts index d8b79bee13025..f770cfcc45e4b 100644 --- a/packages/core/http/core-http-server/src/router/router.ts +++ b/packages/core/http/core-http-server/src/router/router.ts @@ -10,7 +10,7 @@ import type { Request, ResponseObject, ResponseToolkit } from '@hapi/hapi'; import type Boom from '@hapi/boom'; import type { VersionedRouter } from '../versioning'; -import type { RouteConfig, RouteDeprecationInfo, RouteMethod } from './route'; +import type { RouteAccess, RouteConfig, RouteDeprecationInfo, RouteMethod } from './route'; import type { RequestHandler, RequestHandlerWrapper } from './request_handler'; import type { RequestHandlerContextBase } from './request_handler_context'; import type { RouteConfigOptions } from './route'; @@ -143,9 +143,22 @@ export interface RouterRoute { } /** @public */ -export interface RouterDeprecatedRouteDetails { - routeDeprecationOptions: RouteDeprecationInfo; +export interface RouterDeprecatedApiDetails { + routeDeprecationOptions?: RouteDeprecationInfo; routeMethod: RouteMethod; routePath: string; routeVersion?: string; + routeAccess?: RouteAccess; +} + +/** @public */ +export interface RouterRouteDeprecatedApiDetails extends RouterDeprecatedApiDetails { + routeAccess: 'public'; + routeDeprecationOptions: RouteDeprecationInfo; +} + +/** @public */ +export interface RouterAccessDeprecatedApiDetails extends RouterDeprecatedApiDetails { + routeAccess: 'internal'; + routeDeprecationOptions?: RouteDeprecationInfo; } diff --git a/packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts b/packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts index 39df9d30d19c9..e713e3e905a47 100644 --- a/packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts +++ b/packages/core/usage-data/core-usage-data-server/src/core_usage_stats.ts @@ -145,6 +145,9 @@ export interface CoreUsageStats { 'savedObjectsRepository.resolvedOutcome.conflict'?: number; 'savedObjectsRepository.resolvedOutcome.notFound'?: number; 'savedObjectsRepository.resolvedOutcome.total'?: number; + // API Deprecations counters + 'deprecated_api_calls_resolved.total'?: number; + 'deprecated_api_calls.total'?: number; } /** diff --git a/src/plugins/kibana_usage_collection/server/collectors/core/core_usage_collector.ts b/src/plugins/kibana_usage_collection/server/collectors/core/core_usage_collector.ts index b969215f508df..41e7bf9fd7402 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/core/core_usage_collector.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/core/core_usage_collector.ts @@ -1183,6 +1183,18 @@ export function getCoreUsageCollector( 'How many times a saved object has resolved with any of the four possible outcomes.', }, }, + 'deprecated_api_calls_resolved.total': { + type: 'integer', + _meta: { + description: 'How many times deprecated APIs has been marked as resolved', + }, + }, + 'deprecated_api_calls.total': { + type: 'integer', + _meta: { + description: 'How many times deprecated APIs has been called.', + }, + }, }, fetch() { return getCoreUsageDataService().getCoreUsageData(); diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index aed47fa83964a..6a43177492548 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -9290,6 +9290,18 @@ "_meta": { "description": "How many times a saved object has resolved with any of the four possible outcomes." } + }, + "deprecated_api_calls_resolved.total": { + "type": "integer", + "_meta": { + "description": "How many times deprecated APIs has been marked as resolved" + } + }, + "deprecated_api_calls.total": { + "type": "integer", + "_meta": { + "description": "How many times deprecated APIs has been called." + } } } }, @@ -10887,12 +10899,6 @@ "description": "Non-default value of setting." } }, - "observability:newLogsOverview": { - "type": "boolean", - "_meta": { - "description": "Enable the new logs overview component." - } - }, "observability:searchExcludedDataTiers": { "type": "array", "items": { @@ -10901,6 +10907,12 @@ "description": "Non-default value of setting." } } + }, + "observability:newLogsOverview": { + "type": "boolean", + "_meta": { + "description": "Enable the new logs overview component." + } } } }, diff --git a/x-pack/plugins/upgrade_assistant/README.md b/x-pack/plugins/upgrade_assistant/README.md index 9e2cf1b47e60a..531d4c1702c04 100644 --- a/x-pack/plugins/upgrade_assistant/README.md +++ b/x-pack/plugins/upgrade_assistant/README.md @@ -21,14 +21,14 @@ When we want to enable ML model snapshot deprecation warnings again we need to c There are three sources of deprecation information: -* [**Elasticsearch Deprecation Info API.**](https://www.elastic.co/guide/en/elasticsearch/reference/master/migration-api-deprecation.html) +* [**Elasticsearch Deprecation Info API.**](https://www.elastic.co/guide/en/elasticsearch/reference/main/migration-api-deprecation.html) This is information about Elasticsearch cluster, node, Machine Learning, and index-level settings that use deprecated features that will be removed or changed in the next major version. ES server engineers are responsible for adding deprecations to the Deprecation Info API. * [**Elasticsearch deprecation logs.**](https://www.elastic.co/guide/en/elasticsearch/reference/current/logging.html#deprecation-logging) These surface runtime deprecations, e.g. a Painless script that uses a deprecated accessor or a request to a deprecated API. These are also generally surfaced as deprecation headers within the response. Even if the cluster state is good, app maintainers need to watch the logs in case deprecations are discovered as data is migrated. Starting in 7.x, deprecation logs can be written to a file or a data stream ([#58924](https://github.com/elastic/elasticsearch/pull/58924)). When the data stream exists, the Upgrade Assistant provides a way to analyze the logs through Observability or Discover ([#106521](https://github.com/elastic/kibana/pull/106521)). -* [**Kibana deprecations API.**](https://github.com/elastic/kibana/blob/master/src/core/server/deprecations/README.mdx) This is information about deprecated features and configs in Kibana. These deprecations are only communicated to the user if the deployment is using these features. Kibana engineers are responsible for adding deprecations to the deprecations API for their respective team. +* [**Kibana deprecations API.**](https://github.com/elastic/kibana/blob/main/src/core/server/deprecations/README.mdx) This is information about deprecated features and configs in Kibana. These deprecations are only communicated to the user if the deployment is using these features. Kibana engineers are responsible for adding deprecations to the deprecations API for their respective team. ### Fixing problems @@ -284,23 +284,27 @@ yarn start --plugin-path=examples/routing_example --plugin-path=examples/develop The following comprehensive deprecated routes examples are registered inside the folder: `examples/routing_example/server/routes/deprecated_routes` Run them in the console to trigger the deprecation condition so they show up in the UA: +We need to explicitly set the query param `elasticInternalOrigin` to `false` to track the request as non-internal origin. ``` -# Versioned routes: Version 1 is deprecated -GET kbn:/api/routing_example/d/versioned?apiVersion=1 -GET kbn:/api/routing_example/d/versioned?apiVersion=2 - -# Non-versioned routes -GET kbn:/api/routing_example/d/removed_route -GET kbn:/api/routing_example/d/deprecated_route -POST kbn:/api/routing_example/d/migrated_route +# Route deprecations for Versioned routes +GET kbn:/api/routing_example/d/versioned_route?apiVersion=2023-10-31&elasticInternalOrigin=false + +# Route deprecations for Non-versioned routes +GET kbn:/api/routing_example/d/removed_route?elasticInternalOrigin=false +GET kbn:/api/routing_example/d/deprecated_route?elasticInternalOrigin=false +POST kbn:/api/routing_example/d/migrated_route?elasticInternalOrigin=false {} + +# Access deprecations +GET kbn:/api/routing_example/d/internal_deprecated_route?elasticInternalOrigin=false +GET kbn:/internal/routing_example/d/internal_only_route?elasticInternalOrigin=false +GET kbn:/internal/routing_example/d/internal_versioned_route?apiVersion=1&elasticInternalOrigin=false ``` 1. You can also mark as deprecated in the UA to remove the deprecation from the list. 2. Check the telemetry response to see the reported data about the deprecated route. -3. Calling version 2 of the API does not do anything since it is not deprecated unlike version `1` (`GET kbn:/api/routing_example/d/versioned?apiVersion=2`) -4. Internally you can see the deprecations counters from the dev console by running the following: +3. Internally you can see the deprecations counters from the dev console by running the following: ``` GET .kibana_usage_counters/_search { @@ -331,7 +335,7 @@ This is a non-exhaustive list of different error scenarios in Upgrade Assistant. ### Telemetry -The Upgrade Assistant tracks several triggered events in the UI, using Kibana Usage Collection service's [UI counters](https://github.com/elastic/kibana/blob/master/src/plugins/usage_collection/README.mdx#ui-counters). +The Upgrade Assistant tracks several triggered events in the UI, using Kibana Usage Collection service's [UI counters](https://github.com/elastic/kibana/blob/main/src/plugins/usage_collection/README.mdx#ui-counters). **Overview page** - Component loaded @@ -350,6 +354,6 @@ The Upgrade Assistant tracks several triggered events in the UI, using Kibana Us - Component loaded - Click event for "Quick resolve" button -In addition to UI counters, the Upgrade Assistant has a [custom usage collector](https://github.com/elastic/kibana/blob/master/src/plugins/usage_collection/README.mdx#custom-collector). It currently is only responsible for tracking whether the user has deprecation logging enabled or not. +In addition to UI counters, the Upgrade Assistant has a [custom usage collector](https://github.com/elastic/kibana/blob/main/src/plugins/usage_collection/README.mdx#custom-collector). It currently is only responsible for tracking whether the user has deprecation logging enabled or not. -For testing instructions, refer to the [Kibana Usage Collection service README](https://github.com/elastic/kibana/blob/master/src/plugins/usage_collection/README.mdx#testing). \ No newline at end of file +For testing instructions, refer to the [Kibana Usage Collection service README](https://github.com/elastic/kibana/blob/main/src/plugins/usage_collection/README.mdx#testing). \ No newline at end of file diff --git a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/api_deprecations.ts b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/api_deprecations.ts index f146bf38f5f26..bbce39e9fb29a 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/api_deprecations.ts +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/api_deprecations.ts @@ -7,21 +7,19 @@ import expect from '@kbn/expect'; import { expect as expectExpect } from 'expect'; -import type { DomainDeprecationDetails } from '@kbn/core-deprecations-common'; -import { ApiDeprecationDetails } from '@kbn/core-deprecations-common/src/types'; import { setTimeout as setTimeoutAsync } from 'timers/promises'; import { UsageCountersSavedObject } from '@kbn/usage-collection-plugin/server'; import _ from 'lodash'; +import type { + ApiDeprecationDetails, + DomainDeprecationDetails, +} from '@kbn/core-deprecations-common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -interface DomainApiDeprecationDetails extends ApiDeprecationDetails { - domainId: string; -} - const getApiDeprecations = (allDeprecations: DomainDeprecationDetails[]) => { return allDeprecations.filter( (deprecation) => deprecation.deprecationType === 'api' - ) as unknown as DomainApiDeprecationDetails[]; + ) as unknown as Array>; }; export default function ({ getService }: FtrProviderContext) { @@ -30,7 +28,10 @@ export default function ({ getService }: FtrProviderContext) { const retry = getService('retry'); const es = getService('es'); - describe('Kibana API Deprecations', () => { + describe('Kibana API Deprecations', function () { + // bail on first error in this suite since cases sequentially depend on each other + this.bail(true); + before(async () => { // await kibanaServer.savedObjects.cleanStandardList(); await esArchiver.emptyKibanaIndex(); @@ -42,6 +43,9 @@ export default function ({ getService }: FtrProviderContext) { }); it('returns deprecated APIs when the api is called', async () => { + await supertest + .get(`/internal/routing_example/d/internal_versioned_route?apiVersion=1`) + .expect(200); await supertest.get(`/api/routing_example/d/removed_route`).expect(200); // sleep a little until the usage counter is synced into ES @@ -51,7 +55,7 @@ export default function ({ getService }: FtrProviderContext) { async () => { const { deprecations } = (await supertest.get(`/api/deprecations/`).expect(200)).body; const apiDeprecations = getApiDeprecations(deprecations); - expect(apiDeprecations.length).to.equal(1); + expect(apiDeprecations.length).to.equal(2); expectExpect(apiDeprecations[0].correctiveActions.mark_as_resolved_api).toEqual({ routePath: '/api/routing_example/d/removed_route', @@ -68,6 +72,23 @@ export default function ({ getService }: FtrProviderContext) { expectExpect(apiDeprecations[0].title).toEqual( 'The "GET /api/routing_example/d/removed_route" route is removed' ); + + expectExpect(apiDeprecations[1].correctiveActions.mark_as_resolved_api).toEqual({ + routePath: '/internal/routing_example/d/internal_versioned_route', + routeMethod: 'get', + routeVersion: '1', + apiTotalCalls: 1, + totalMarkedAsResolved: 0, + timestamp: expectExpect.any(String), + }); + + expectExpect(apiDeprecations[1].domainId).toEqual('core.api_deprecations'); + expectExpect(apiDeprecations[1].apiId).toEqual( + '1|get|/internal/routing_example/d/internal_versioned_route' + ); + expectExpect(apiDeprecations[1].title).toEqual( + 'The "GET /internal/routing_example/d/internal_versioned_route" API is internal to Elastic' + ); }, undefined, 2000 @@ -76,7 +97,7 @@ export default function ({ getService }: FtrProviderContext) { it('no longer returns deprecated API when it is marked as resolved', async () => { await supertest - .post(`/api/deprecations/mark_as_resolved`) + .post(`/api/deprecations/mark_as_resolved?elasticInternalOrigin=true`) .set('kbn-xsrf', 'xxx') .send({ domainId: 'core.api_deprecations', @@ -91,7 +112,10 @@ export default function ({ getService }: FtrProviderContext) { await retry.tryForTime(15 * 1000, async () => { const { deprecations } = (await supertest.get(`/api/deprecations/`).expect(200)).body; const apiDeprecations = getApiDeprecations(deprecations); - expect(apiDeprecations.length).to.equal(0); + expect(apiDeprecations.length).to.equal(1); + expectExpect(apiDeprecations[0].apiId).toEqual( + '1|get|/internal/routing_example/d/internal_versioned_route' + ); }); }); @@ -105,7 +129,7 @@ export default function ({ getService }: FtrProviderContext) { async () => { const { deprecations } = (await supertest.get(`/api/deprecations/`).expect(200)).body; const apiDeprecations = getApiDeprecations(deprecations); - expect(apiDeprecations.length).to.equal(1); + expect(apiDeprecations.length).to.equal(2); expectExpect(apiDeprecations[0].correctiveActions.mark_as_resolved_api).toEqual({ routePath: '/api/routing_example/d/removed_route', @@ -132,31 +156,80 @@ export default function ({ getService }: FtrProviderContext) { }, }); - expect(hits.hits.length).to.equal(3); + expect(hits.hits.length).to.equal(4); const counters = hits.hits.map((hit) => hit._source!['usage-counter']).sort(); - expectExpect(_.sortBy(counters, 'counterType')).toEqual([ - { - count: 1, - counterName: 'unversioned|get|/api/routing_example/d/removed_route', - counterType: 'deprecated_api_call:marked_as_resolved', - domainId: 'core', - source: 'server', - }, - { - count: 1, - counterName: 'unversioned|get|/api/routing_example/d/removed_route', - counterType: 'deprecated_api_call:resolved', - domainId: 'core', - source: 'server', - }, - { - count: 2, - counterName: 'unversioned|get|/api/routing_example/d/removed_route', - counterType: 'deprecated_api_call:total', - domainId: 'core', - source: 'server', - }, - ]); + expectExpect(_.sortBy(counters, 'counterType')).toEqual(expectedSuiteUsageCounters); + }); + + it('Does not increment internal origin calls', async () => { + await supertest + .get(`/api/routing_example/d/removed_route?elasticInternalOrigin=true`) + .expect(200); + // call another deprecated api to make sure that we are not verifying stale results + await supertest + .get(`/api/routing_example/d/versioned_route?apiVersion=2023-10-31`) + .expect(200); + + // sleep a little until the usage counter is synced into ES + await setTimeoutAsync(3000); + await retry.tryForTime(15 * 1000, async () => { + const should = ['total', 'resolved', 'marked_as_resolved'].map((type) => ({ + match: { 'usage-counter.counterType': `deprecated_api_call:${type}` }, + })); + + const { hits } = await es.search<{ 'usage-counter': UsageCountersSavedObject }>({ + index: '.kibana_usage_counters', + body: { + query: { bool: { should } }, + }, + }); + + expect(hits.hits.length).to.equal(5); + const counters = hits.hits.map((hit) => hit._source!['usage-counter']).sort(); + expectExpect(_.sortBy(counters, 'counterType')).toEqual( + [ + ...expectedSuiteUsageCounters, + { + domainId: 'core', + counterName: '2023-10-31|get|/api/routing_example/d/versioned_route', + counterType: 'deprecated_api_call:total', + source: 'server', + count: 1, + }, + ].sort() + ); + }); }); }); } + +const expectedSuiteUsageCounters = [ + { + domainId: 'core', + counterName: 'unversioned|get|/api/routing_example/d/removed_route', + counterType: 'deprecated_api_call:marked_as_resolved', + source: 'server', + count: 1, + }, + { + domainId: 'core', + counterName: 'unversioned|get|/api/routing_example/d/removed_route', + counterType: 'deprecated_api_call:resolved', + source: 'server', + count: 1, + }, + { + domainId: 'core', + counterName: '1|get|/internal/routing_example/d/internal_versioned_route', + counterType: 'deprecated_api_call:total', + source: 'server', + count: 1, + }, + { + domainId: 'core', + counterName: 'unversioned|get|/api/routing_example/d/removed_route', + counterType: 'deprecated_api_call:total', + source: 'server', + count: 2, + }, +]; From be1a4bbe4095079643d8e31d7cc967f6f91aa57a Mon Sep 17 00:00:00 2001 From: Vadim Kibana <82822460+vadimkibana@users.noreply.github.com> Date: Tue, 12 Nov 2024 12:59:36 +0100 Subject: [PATCH 015/105] [ES|QL] `STATS` command APIs (#199322) ## Summary Partially addresses https://github.com/elastic/kibana/issues/191812 This PR implement higher-level convenience methods for working with `STATS` commands: - `commands.stats.list()` - iterates over all `STATS` commands. - `commands.stats.byIndex()` - retrieves the Nth `STATS` command. - `commands.stats.summarize()` - returns summary about fields used in aggregates and grouping for all `STATS` commands in the query. - `commands.stats.summarizeCommand()` - same as `.summarize()`, but returns a summary only about the requested command. Usage: ```ts const query = EsqlQuery.fromSrc('FROM index | STATS a = max(b)'); const summary = commands.stats.summarize(query); // [ { aggregates: { a: { fields: ['b'] }} ] ``` ### 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 ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#_add_your_labels) --- .../kbn-esql-ast/src/mutate/commands/index.ts | 3 +- .../src/mutate/commands/stats/index.test.ts | 317 ++++++++++++++++++ .../src/mutate/commands/stats/index.ts | 234 +++++++++++++ packages/kbn-esql-ast/src/query/query.ts | 4 + 4 files changed, 557 insertions(+), 1 deletion(-) create mode 100644 packages/kbn-esql-ast/src/mutate/commands/stats/index.test.ts create mode 100644 packages/kbn-esql-ast/src/mutate/commands/stats/index.ts diff --git a/packages/kbn-esql-ast/src/mutate/commands/index.ts b/packages/kbn-esql-ast/src/mutate/commands/index.ts index 9e2599c493459..8068aa5d3ef94 100644 --- a/packages/kbn-esql-ast/src/mutate/commands/index.ts +++ b/packages/kbn-esql-ast/src/mutate/commands/index.ts @@ -10,5 +10,6 @@ import * as from from './from'; import * as limit from './limit'; import * as sort from './sort'; +import * as stats from './stats'; -export { from, limit, sort }; +export { from, limit, sort, stats }; diff --git a/packages/kbn-esql-ast/src/mutate/commands/stats/index.test.ts b/packages/kbn-esql-ast/src/mutate/commands/stats/index.test.ts new file mode 100644 index 0000000000000..6fdafa45e3831 --- /dev/null +++ b/packages/kbn-esql-ast/src/mutate/commands/stats/index.test.ts @@ -0,0 +1,317 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import * as commands from '..'; +import { EsqlQuery } from '../../../query'; + +describe('commands.stats', () => { + describe('.list()', () => { + it('lists all "STATS" commands', () => { + const src = 'FROM index | LIMIT 1 | STATS agg() | LIMIT 2 | STATS max()'; + const query = EsqlQuery.fromSrc(src); + + const nodes = [...commands.stats.list(query.ast)]; + + expect(nodes).toMatchObject([ + { + type: 'command', + name: 'stats', + args: [ + { + type: 'function', + name: 'agg', + }, + ], + }, + { + type: 'command', + name: 'stats', + args: [ + { + type: 'function', + name: 'max', + }, + ], + }, + ]); + }); + }); + + describe('.byIndex()', () => { + it('retrieves the specific "STATS" command by index', () => { + const src = 'FROM index | LIMIT 1 | STATS agg() | LIMIT 2 | STATS max()'; + const query = EsqlQuery.fromSrc(src); + + const node1 = commands.stats.byIndex(query.ast, 1); + const node2 = commands.stats.byIndex(query.ast, 0); + + expect(node1).toMatchObject({ + type: 'command', + name: 'stats', + args: [ + { + type: 'function', + name: 'max', + }, + ], + }); + expect(node2).toMatchObject({ + type: 'command', + name: 'stats', + args: [ + { + type: 'function', + name: 'agg', + }, + ], + }); + }); + }); + + describe('.summarizeCommand()', () => { + it('returns summary of a simple field, defined through assignment', () => { + const src = 'FROM index | STATS foo = agg(bar)'; + const query = EsqlQuery.fromSrc(src); + + const command = commands.stats.byIndex(query.ast, 0)!; + const summary = commands.stats.summarizeCommand(query, command); + + expect(summary).toMatchObject({ + command, + aggregates: { + foo: { + arg: { + type: 'function', + name: '=', + }, + field: 'foo', + column: { + type: 'column', + name: 'foo', + }, + definition: { + type: 'function', + name: 'agg', + args: [ + { + type: 'column', + name: 'bar', + }, + ], + }, + terminals: [ + { + type: 'column', + name: 'bar', + }, + ], + fields: ['bar'], + }, + }, + }); + }); + + it('can summarize field defined without assignment', () => { + const src = 'FROM index | STATS agg( /* haha 😅 */ max(foo), bar, baz)'; + const query = EsqlQuery.fromSrc(src); + + const command = commands.stats.byIndex(query.ast, 0)!; + const summary = commands.stats.summarizeCommand(query, command); + + expect(summary).toMatchObject({ + command, + aggregates: { + '`agg( /* haha 😅 */ max(foo), bar, baz)`': { + arg: { + type: 'function', + name: 'agg', + }, + field: '`agg( /* haha 😅 */ max(foo), bar, baz)`', + column: { + type: 'column', + name: '`agg( /* haha 😅 */ max(foo), bar, baz)`', + }, + definition: { + type: 'function', + name: 'agg', + }, + terminals: [ + { + type: 'column', + name: 'foo', + }, + { + type: 'column', + name: 'bar', + }, + { + type: 'column', + name: 'baz', + }, + ], + fields: ['foo', 'bar', 'baz'], + }, + }, + }); + }); + + it('returns a map of stats about two fields', () => { + const src = 'FROM index | STATS foo = agg(f1) + agg(f2), a.b = agg(f3)'; + const query = EsqlQuery.fromSrc(src); + + const command = commands.stats.byIndex(query.ast, 0)!; + const summary = commands.stats.summarizeCommand(query, command); + + expect(summary).toMatchObject({ + aggregates: { + foo: { + field: 'foo', + fields: ['f1', 'f2'], + }, + 'a.b': { + field: 'a.b', + fields: ['f3'], + }, + }, + }); + expect(summary.fields).toEqual(new Set(['f1', 'f2', 'f3'])); + }); + + it('can get de-duplicated list of used fields', () => { + const src = 'FROM index | STATS foo = agg(f1) + agg(f2), a.b = agg(f1)'; + const query = EsqlQuery.fromSrc(src); + + const command = commands.stats.byIndex(query.ast, 0)!; + const summary = commands.stats.summarizeCommand(query, command); + + expect(summary.fields).toEqual(new Set(['f1', 'f2'])); + }); + + describe('params', () => { + it('can use params as source field names', () => { + const src = 'FROM index | STATS foo = agg(f1.?aha) + ?aha(?nested.?param), a.b = agg(f1)'; + const query = EsqlQuery.fromSrc(src); + + const command = commands.stats.byIndex(query.ast, 0)!; + const summary = commands.stats.summarizeCommand(query, command); + + expect(summary).toMatchObject({ + aggregates: { + foo: { + fields: ['f1.?aha', '?nested.?param'], + }, + 'a.b': { + fields: ['f1'], + }, + }, + }); + expect(summary.fields).toEqual(new Set(['f1.?aha', '?nested.?param', 'f1'])); + }); + + it('can use params as destination field names', () => { + const src = 'FROM index | STATS ?dest = agg(asdf) BY asdf'; + const query = EsqlQuery.fromSrc(src); + + const command = commands.stats.byIndex(query.ast, 0)!; + const summary = commands.stats.summarizeCommand(query, command); + + expect(summary).toMatchObject({ + aggregates: { + '?dest': { + fields: ['asdf'], + }, + }, + }); + expect(summary.fields).toEqual(new Set(['asdf'])); + }); + }); + + describe('BY option', () => { + it('can collect fields from the BY option', () => { + const src = 'FROM index | STATS max(1) BY abc'; + const query = EsqlQuery.fromSrc(src); + + const command = commands.stats.byIndex(query.ast, 0)!; + const summary = commands.stats.summarizeCommand(query, command); + + expect(summary.aggregates).toEqual({ + '`max(1)`': expect.any(Object), + }); + expect(summary.fields).toEqual(new Set(['abc'])); + }); + + it('returns all "grouping" fields', () => { + const src = 'FROM index | STATS max(1) BY a, b, c'; + const query = EsqlQuery.fromSrc(src); + + const command = commands.stats.byIndex(query.ast, 0)!; + const summary = commands.stats.summarizeCommand(query, command); + + expect(summary.aggregates).toEqual({ + '`max(1)`': expect.any(Object), + }); + expect(summary.grouping).toMatchObject({ + a: { type: 'column' }, + b: { type: 'column' }, + c: { type: 'column' }, + }); + }); + + it('can have params and quoted fields in grouping', () => { + const src = 'FROM index | STATS max(1) BY `a😎`, ?123, a.?b.?0.`😎`'; + const query = EsqlQuery.fromSrc(src); + + const command = commands.stats.byIndex(query.ast, 0)!; + const summary = commands.stats.summarizeCommand(query, command); + + expect(summary.aggregates).toEqual({ + '`max(1)`': expect.any(Object), + }); + expect(summary.grouping).toMatchObject({ + '`a😎`': { type: 'column' }, + // '?123': { type: 'column' }, + 'a.?b.?0.`😎`': { type: 'column' }, + }); + }); + }); + }); + + describe('.summarize()', () => { + it('can summarize multiple stats commands', () => { + const src = 'FROM index | LIMIT 1 | STATS agg() | LIMIT 2 | STATS max(a, b, c), max2(d.e)'; + const query = EsqlQuery.fromSrc(src); + const summary = commands.stats.summarize(query); + + expect(summary).toMatchObject([ + { + aggregates: { + '`agg()`': { + field: '`agg()`', + fields: [], + }, + }, + fields: new Set([]), + }, + { + aggregates: { + '`max(a, b, c)`': { + field: '`max(a, b, c)`', + fields: ['a', 'b', 'c'], + }, + '`max2(d.e)`': { + field: '`max2(d.e)`', + fields: ['d.e'], + }, + }, + fields: new Set(['a', 'b', 'c', 'd.e']), + }, + ]); + }); + }); +}); diff --git a/packages/kbn-esql-ast/src/mutate/commands/stats/index.ts b/packages/kbn-esql-ast/src/mutate/commands/stats/index.ts new file mode 100644 index 0000000000000..9a07549c0e0ef --- /dev/null +++ b/packages/kbn-esql-ast/src/mutate/commands/stats/index.ts @@ -0,0 +1,234 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { Walker } from '../../../walker'; +import { Visitor } from '../../../visitor'; +import { LeafPrinter } from '../../../pretty_print'; +import { Builder } from '../../../builder'; +import { singleItems } from '../../../visitor/utils'; +import type { + ESQLAstQueryExpression, + ESQLColumn, + ESQLCommand, + ESQLList, + ESQLLiteral, + ESQLProperNode, + ESQLTimeInterval, +} from '../../../types'; +import * as generic from '../../generic'; +import { isColumn, isFunctionExpression } from '../../../ast/helpers'; +import type { EsqlQuery } from '../../../query'; + +/** + * Lists all "LIMIT" commands in the query AST. + * + * @param ast The root AST node to search for "LIMIT" commands. + * @returns A collection of "LIMIT" commands. + */ +export const list = (ast: ESQLAstQueryExpression): IterableIterator => { + return generic.commands.list(ast, (cmd) => cmd.name === 'stats'); +}; + +/** + * Retrieves the "LIMIT" command at the specified index in order of appearance. + * + * @param ast The root AST node to search for "LIMIT" commands. + * @param index The index of the "LIMIT" command to retrieve. + * @returns The "LIMIT" command at the specified index, if any. + */ +export const byIndex = (ast: ESQLAstQueryExpression, index: number): ESQLCommand | undefined => { + return [...list(ast)][index]; +}; + +/** + * Summary of a STATS command. + */ +export interface StatsCommandSummary { + /** + * The "STATS" command AST node from which this summary was produced. + */ + command: ESQLCommand; + + /** + * Summary of the main arguments of the "STATS" command. + */ + aggregates: Record; + + /** + * Summary of the "BY" arguments of the "STATS" command. + */ + grouping: Record; + + /** + * De-duplicated list all of ES|QL-syntax formatted field names from the + * {@link aggregates} and {@link grouping} fields. + */ + fields: Set; +} + +/** + * Summary of STATS command "aggregates" section (main arguments). + * + * STATS [ BY ] + */ +export interface StatsAggregatesSummary { + /** + * STATS command argument AST node (as was parsed). + */ + arg: ESQLProperNode; + + /** + * The field name, correctly formatted, extracted from the AST. + */ + field: string; + + /** + * A `column` AST node, which represents the field name. If no column AST node + * was found, a new one "virtual" column node is created. + */ + column: ESQLColumn; + + /** + * The definition of the field, which is the right-hand side of the `=` + * operator, or the argument itself if no `=` operator is present. + */ + definition: ESQLProperNode; + + /** + * A list of terminal nodes that were found in the definition. + */ + terminals: Array; + + /** + * Correctly formatted list of field names that were found in the {@link terminals}. + */ + fields: string[]; +} + +const summarizeArgParts = ( + query: EsqlQuery, + arg: ESQLProperNode +): [column: ESQLColumn, definition: ESQLProperNode] => { + if (isFunctionExpression(arg) && arg.name === '=' && isColumn(arg.args[0])) { + const [column, definition] = singleItems(arg.args); + + return [column as ESQLColumn, definition as ESQLProperNode]; + } + + const name = [...query.src].slice(arg.location.min, arg.location.max + 1).join(''); + const args = [Builder.identifier({ name })]; + const column = Builder.expression.column({ args }); + + return [column, arg]; +}; + +const summarizeArg = (query: EsqlQuery, arg: ESQLProperNode): StatsAggregatesSummary => { + const [column, definition] = summarizeArgParts(query, arg); + const terminals: StatsAggregatesSummary['terminals'] = []; + const fields: StatsAggregatesSummary['fields'] = []; + + Walker.walk(definition, { + visitLiteral(node) { + terminals.push(node); + }, + visitColumn(node) { + terminals.push(node); + fields.push(LeafPrinter.column(node)); + }, + visitListLiteral(node) { + terminals.push(node); + }, + visitTimeIntervalLiteral(node) { + terminals.push(node); + }, + }); + + const summary: StatsAggregatesSummary = { + arg, + field: LeafPrinter.column(column), + column, + definition, + terminals, + fields, + }; + + return summary; +}; + +/** + * Returns a summary of the STATS command. + * + * @param query Query which contains the AST and source code. + * @param command The STATS command AST node to summarize. + * @returns Summary of the STATS command. + */ +export const summarizeCommand = (query: EsqlQuery, command: ESQLCommand): StatsCommandSummary => { + const aggregates: StatsCommandSummary['aggregates'] = {}; + const grouping: StatsCommandSummary['grouping'] = {}; + const fields: StatsCommandSummary['fields'] = new Set(); + + // Process main arguments, the "aggregates" part of the command. + new Visitor() + .on('visitExpression', (ctx) => { + const summary = summarizeArg(query, ctx.node); + aggregates[summary.field] = summary; + for (const field of summary.fields) fields.add(field); + }) + .on('visitCommand', () => {}) + .on('visitStatsCommand', (ctx) => { + for (const _ of ctx.visitArguments()); + }) + .visitCommand(command); + + // Process the "BY" arguments, the "grouping" part of the command. + new Visitor() + .on('visitExpression', () => {}) + .on('visitColumnExpression', (ctx) => { + const column = ctx.node; + const formatted = LeafPrinter.column(column); + grouping[formatted] = column; + fields.add(formatted); + }) + .on('visitCommandOption', (ctx) => { + if (ctx.node.name !== 'by') return; + for (const _ of ctx.visitArguments()); + }) + .on('visitCommand', () => {}) + .on('visitStatsCommand', (ctx) => { + for (const _ of ctx.visitOptions()); + }) + .visitCommand(command); + + const summary: StatsCommandSummary = { + command, + aggregates, + grouping, + fields, + }; + + return summary; +}; + +/** + * Summarizes all STATS commands in the query. + * + * @param query Query to summarize. + * @returns Returns a list of summaries for all STATS commands in the query in + * order of appearance. + */ +export const summarize = (query: EsqlQuery): StatsCommandSummary[] => { + const summaries: StatsCommandSummary[] = []; + + for (const command of list(query.ast)) { + const summary = summarizeCommand(query, command); + summaries.push(summary); + } + + return summaries; +}; diff --git a/packages/kbn-esql-ast/src/query/query.ts b/packages/kbn-esql-ast/src/query/query.ts index 60435cc64c977..66c9fd58df085 100644 --- a/packages/kbn-esql-ast/src/query/query.ts +++ b/packages/kbn-esql-ast/src/query/query.ts @@ -15,6 +15,10 @@ import { WrappingPrettyPrinterOptions, } from '../pretty_print/wrapping_pretty_printer'; +/** + * Represents a parsed or programmatically created ES|QL query. Keeps track of + * the AST, source code, and optionally lexer tokens. + */ export class EsqlQuery { public static readonly fromSrc = (src: string, opts?: ParseOptions): EsqlQuery => { const { root, tokens } = parse(src, opts); From 13ae98602f1979bab413cefe57e3685510adc3d3 Mon Sep 17 00:00:00 2001 From: Ania Kowalska <63072419+akowalska622@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:01:16 +0100 Subject: [PATCH 016/105] [Discover] fix: responsive data view picker (#199617) ## Summary Closes https://github.com/elastic/kibana/issues/199434 `ChangeDataView` had two problems on smaller screens: 1. The `Data view` label was wrapped across two rows, causing the parent container to expand and misalign with the picker. 2. The picker container was overflowing, and the text was not truncated. ![image](https://github.com/user-attachments/assets/1eeb5cf2-bcae-4a1d-b28c-13c5c508b4c1) Setting `min-width: 0` on two parent containers solved the problem: Screenshot 2024-11-11 at 11 52 09 ![data-view-picker](https://github.com/user-attachments/assets/08e23d5a-7f09-4530-aca5-bac7fa0da7cd) ### Checklist Delete any items that are not applicable to this PR. - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#_add_your_labels) - [ ] This will appear in the **Release Notes** and follow the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../public/dataview_picker/change_dataview.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx index ade754004b8ef..d89621d598679 100644 --- a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx +++ b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx @@ -43,6 +43,10 @@ const mapAdHocDataView = (adHocDataView: DataView): DataViewListItemEnhanced => }; }; +const shrinkableContainerCss = css` + min-width: 0; +`; + export function ChangeDataView({ isMissingCurrent, currentDataViewId, @@ -238,7 +242,7 @@ export function ChangeDataView({ return ( <> - + - + Date: Tue, 12 Nov 2024 13:01:36 +0100 Subject: [PATCH 017/105] [Custom threshold] Fix the custom equation label on the preview lens chart (#199618) Fixes #181876 ## Summary This PR fixes the custom equation label on the preview lens chart. |With label|Without label|With group by field| |---|---|---| |![image](https://github.com/user-attachments/assets/b4f1a1e7-8e67-4b24-ae48-379fe393f90a)|![image](https://github.com/user-attachments/assets/3ef2733f-9ce8-4b37-8ecf-c19c1371aced)|![image](https://github.com/user-attachments/assets/d638f49e-98e2-4df7-8852-84dc62b9f739)| --- .../components/rule_condition_chart/rule_condition_chart.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability_solution/observability/public/components/rule_condition_chart/rule_condition_chart.tsx b/x-pack/plugins/observability_solution/observability/public/components/rule_condition_chart/rule_condition_chart.tsx index 407637520dda7..4567d7c37b10b 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/rule_condition_chart/rule_condition_chart.tsx +++ b/x-pack/plugins/observability_solution/observability/public/components/rule_condition_chart/rule_condition_chart.tsx @@ -68,6 +68,7 @@ export interface RuleConditionChartExpressions { timeSize?: number; timeUnit?: TimeUnitChar; equation?: string; + label?: string; } export interface RuleConditionChartProps { metricExpression: RuleConditionChartExpressions; @@ -108,6 +109,7 @@ export function RuleConditionChart({ threshold, comparator, equation, + label, warningComparator, warningThreshold, } = metricExpression; @@ -332,7 +334,7 @@ export function RuleConditionChart({ const baseLayer = { type: 'formula', value: formula, - label: formula, + label: label ?? formula, groupBy, format: { id: formatId, @@ -409,6 +411,7 @@ export function RuleConditionChart({ comparator, dataView, equation, + label, searchConfiguration, formula, formulaAsync.value, From 9bb3661060e01628a052e34bd471ecea0b428fa7 Mon Sep 17 00:00:00 2001 From: Elena Shostak <165678770+elena-shostak@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:05:56 +0100 Subject: [PATCH 018/105] Changed log level for message with authz opt out (#199678) ## Summary Changed log level for message with authz opt out from `warn` to `debug` __Closes: https://github.com/elastic/kibana/issues/199677__ --- .../security/server/authorization/api_authorization.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x-pack/plugins/security/server/authorization/api_authorization.ts b/x-pack/plugins/security/server/authorization/api_authorization.ts index 2b99c2a176ac1..888d74e7d7bb2 100644 --- a/x-pack/plugins/security/server/authorization/api_authorization.ts +++ b/x-pack/plugins/security/server/authorization/api_authorization.ts @@ -48,10 +48,6 @@ export function initAPIAuthorization( if (security) { if (isAuthzDisabled(security.authz)) { - logger.warn( - `Route authz is disabled for ${request.url.pathname}${request.url.search}": ${security.authz.reason}` - ); - return toolkit.next(); } From 763b5deafd0eec37e960e499299f1205e6a3e999 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 12 Nov 2024 23:21:58 +1100 Subject: [PATCH 019/105] Unauthorized route migration for routes owned by kibana-core (#198333) ### Authz API migration for unauthorized routes This PR migrates unauthorized routes owned by your team to a new security configuration. Please refer to the documentation for more information: [Authorization API](https://docs.elastic.dev/kibana-dev-docs/key-concepts/security-api-authorization) ### **Before migration:** ```ts router.get({ path: '/api/path', ... }, handler); ``` ### **After migration:** ```ts router.get({ path: '/api/path', security: { authz: { enabled: false, reason: 'This route is opted out from authorization because ...', }, }, ... }, handler); ``` ### What to do next? 1. Review the changes in this PR. 2. Elaborate on the reasoning to opt-out of authorization. 3. Routes without a compelling reason to opt-out of authorization should plan to introduce them as soon as possible. 2. You might need to update your tests to reflect the new security configuration: - If you have snapshot tests that include the route definition. ## Any questions? If you have any questions or need help with API authorization, please reach out to the `@elastic/kibana-security` team. Co-authored-by: Jean-Louis Leysens --- .../server/routes/fetch_es_hits_status.ts | 6 ++ .../server/routes/bulk_delete.ts | 6 ++ .../server/routes/bulk_get.ts | 6 ++ .../server/routes/find.ts | 6 ++ .../server/routes/get_allowed_types.ts | 6 ++ .../server/routes/relationships.ts | 6 ++ .../server/routes/scroll_count.ts | 6 ++ .../server/routes/telemetry_config.ts | 44 +++++++++++++-- .../server/routes/telemetry_last_reported.ts | 56 +++++++++++++++++-- .../server/routes/telemetry_opt_in.ts | 28 +++++++++- .../server/routes/telemetry_opt_in_stats.ts | 6 ++ .../server/routes/telemetry_usage_stats.ts | 28 +++++++++- .../routes/telemetry_user_has_seen_notice.ts | 28 +++++++++- .../server/routes/stats/stats.ts | 6 ++ .../server/routes/ui_counters.ts | 6 ++ .../server/routes/elasticsearch_routes.ts | 28 +++++++--- .../licensing/server/routes/feature_usage.ts | 11 +++- .../plugins/licensing/server/routes/info.ts | 11 +++- .../routes/internal/notify_feature_usage.ts | 6 ++ .../routes/internal/register_feature.ts | 6 ++ 20 files changed, 281 insertions(+), 25 deletions(-) diff --git a/src/plugins/home/server/routes/fetch_es_hits_status.ts b/src/plugins/home/server/routes/fetch_es_hits_status.ts index f01660876210a..aa4c1286ce67e 100644 --- a/src/plugins/home/server/routes/fetch_es_hits_status.ts +++ b/src/plugins/home/server/routes/fetch_es_hits_status.ts @@ -14,6 +14,12 @@ export const registerHitsStatusRoute = (router: IRouter) => { router.post( { path: '/api/home/hits_status', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { body: schema.object({ index: schema.string(), diff --git a/src/plugins/saved_objects_management/server/routes/bulk_delete.ts b/src/plugins/saved_objects_management/server/routes/bulk_delete.ts index ed82726ade0da..da082cc85a1b4 100644 --- a/src/plugins/saved_objects_management/server/routes/bulk_delete.ts +++ b/src/plugins/saved_objects_management/server/routes/bulk_delete.ts @@ -15,6 +15,12 @@ export const registerBulkDeleteRoute = (router: IRouter) => { router.post( { path: '/internal/kibana/management/saved_objects/_bulk_delete', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { body: schema.arrayOf( schema.object({ diff --git a/src/plugins/saved_objects_management/server/routes/bulk_get.ts b/src/plugins/saved_objects_management/server/routes/bulk_get.ts index 9b7c1505cc699..59efd552196c8 100644 --- a/src/plugins/saved_objects_management/server/routes/bulk_get.ts +++ b/src/plugins/saved_objects_management/server/routes/bulk_get.ts @@ -20,6 +20,12 @@ export const registerBulkGetRoute = ( router.post( { path: '/api/kibana/management/saved_objects/_bulk_get', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { body: schema.arrayOf( schema.object({ diff --git a/src/plugins/saved_objects_management/server/routes/find.ts b/src/plugins/saved_objects_management/server/routes/find.ts index 8b37c3550f7da..e1c028a4fab2c 100644 --- a/src/plugins/saved_objects_management/server/routes/find.ts +++ b/src/plugins/saved_objects_management/server/routes/find.ts @@ -34,6 +34,12 @@ export const registerFindRoute = ( router.get( { path: '/api/kibana/management/saved_objects/_find', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { query: schema.object({ perPage: schema.number({ min: 0, defaultValue: 20 }), diff --git a/src/plugins/saved_objects_management/server/routes/get_allowed_types.ts b/src/plugins/saved_objects_management/server/routes/get_allowed_types.ts index c484f5643d8cc..6b89643e8142e 100644 --- a/src/plugins/saved_objects_management/server/routes/get_allowed_types.ts +++ b/src/plugins/saved_objects_management/server/routes/get_allowed_types.ts @@ -23,6 +23,12 @@ export const registerGetAllowedTypesRoute = (router: IRouter) => { router.get( { path: '/api/kibana/management/saved_objects/_allowed_types', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: false, }, async (context, req, res) => { diff --git a/src/plugins/saved_objects_management/server/routes/relationships.ts b/src/plugins/saved_objects_management/server/routes/relationships.ts index 7f06e6a5dabc8..d39f001f2f2a1 100644 --- a/src/plugins/saved_objects_management/server/routes/relationships.ts +++ b/src/plugins/saved_objects_management/server/routes/relationships.ts @@ -21,6 +21,12 @@ export const registerRelationshipsRoute = ( router.get( { path: '/api/kibana/management/saved_objects/relationships/{type}/{id}', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { params: schema.object({ type: schema.string(), diff --git a/src/plugins/saved_objects_management/server/routes/scroll_count.ts b/src/plugins/saved_objects_management/server/routes/scroll_count.ts index 31c01536d6003..3116ca3a22fb1 100644 --- a/src/plugins/saved_objects_management/server/routes/scroll_count.ts +++ b/src/plugins/saved_objects_management/server/routes/scroll_count.ts @@ -17,6 +17,12 @@ export const registerScrollForCountRoute = (router: IRouter) => { router.post( { path: '/api/kibana/management/saved_objects/scroll/counts', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { body: schema.object({ typesToInclude: schema.arrayOf(schema.string()), diff --git a/src/plugins/telemetry/server/routes/telemetry_config.ts b/src/plugins/telemetry/server/routes/telemetry_config.ts index ebc5ca53985e9..700e778ceea27 100644 --- a/src/plugins/telemetry/server/routes/telemetry_config.ts +++ b/src/plugins/telemetry/server/routes/telemetry_config.ts @@ -102,12 +102,46 @@ export function registerTelemetryConfigRoutes({ options: { authRequired: 'optional' }, }) // Just because it used to be /v2/, we are creating identical v1 and v2. - .addVersion({ version: '1', validate: v2Validations }, v2Handler) - .addVersion({ version: '2', validate: v2Validations }, v2Handler); + .addVersion( + { + version: '1', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: v2Validations, + }, + v2Handler + ) + .addVersion( + { + version: '2', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: v2Validations, + }, + v2Handler + ); // Register the deprecated public and path-based for BWC // as we know this one is used by other Elastic products to fetch the opt-in status. - router.versioned - .get({ access: 'public', path: FetchTelemetryConfigRoutePathBasedV2 }) - .addVersion({ version: '2023-10-31', validate: v2Validations }, v2Handler); + router.versioned.get({ access: 'public', path: FetchTelemetryConfigRoutePathBasedV2 }).addVersion( + { + version: '2023-10-31', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: v2Validations, + }, + v2Handler + ); } diff --git a/src/plugins/telemetry/server/routes/telemetry_last_reported.ts b/src/plugins/telemetry/server/routes/telemetry_last_reported.ts index 299d457e080b6..932b7ab8db9cc 100644 --- a/src/plugins/telemetry/server/routes/telemetry_last_reported.ts +++ b/src/plugins/telemetry/server/routes/telemetry_last_reported.ts @@ -40,8 +40,32 @@ export function registerTelemetryLastReported( router.versioned .get({ access: 'internal', path: LastReportedRoute }) // Just because it used to be /v2/, we are creating identical v1 and v2. - .addVersion({ version: '1', validate: v2GetValidations }, v2GetHandler) - .addVersion({ version: '2', validate: v2GetValidations }, v2GetHandler); + .addVersion( + { + version: '1', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: v2GetValidations, + }, + v2GetHandler + ) + .addVersion( + { + version: '2', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: v2GetValidations, + }, + v2GetHandler + ); // PUT to update const v2PutHandler: RequestHandler = async (context, req, res) => { @@ -55,6 +79,30 @@ export function registerTelemetryLastReported( router.versioned .put({ access: 'internal', path: LastReportedRoute }) // Just because it used to be /v2/, we are creating identical v1 and v2. - .addVersion({ version: '1', validate: false }, v2PutHandler) - .addVersion({ version: '2', validate: false }, v2PutHandler); + .addVersion( + { + version: '1', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: false, + }, + v2PutHandler + ) + .addVersion( + { + version: '2', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: false, + }, + v2PutHandler + ); } diff --git a/src/plugins/telemetry/server/routes/telemetry_opt_in.ts b/src/plugins/telemetry/server/routes/telemetry_opt_in.ts index 21b674c3dc45d..de13162ff0619 100644 --- a/src/plugins/telemetry/server/routes/telemetry_opt_in.ts +++ b/src/plugins/telemetry/server/routes/telemetry_opt_in.ts @@ -128,6 +128,30 @@ export function registerTelemetryOptInRoutes({ router.versioned .post({ access: 'internal', path: OptInRoute }) // Just because it used to be /v2/, we are creating identical v1 and v2. - .addVersion({ version: '1', validate: v2Validations }, v2Handler) - .addVersion({ version: '2', validate: v2Validations }, v2Handler); + .addVersion( + { + version: '1', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: v2Validations, + }, + v2Handler + ) + .addVersion( + { + version: '2', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: v2Validations, + }, + v2Handler + ); } diff --git a/src/plugins/telemetry/server/routes/telemetry_opt_in_stats.ts b/src/plugins/telemetry/server/routes/telemetry_opt_in_stats.ts index dcd7790b67e68..0c38b59818500 100644 --- a/src/plugins/telemetry/server/routes/telemetry_opt_in_stats.ts +++ b/src/plugins/telemetry/server/routes/telemetry_opt_in_stats.ts @@ -72,6 +72,12 @@ export function registerTelemetryOptInStatsRoutes( .addVersion( { version: '2023-10-31', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { request: { body: schema.object({ diff --git a/src/plugins/telemetry/server/routes/telemetry_usage_stats.ts b/src/plugins/telemetry/server/routes/telemetry_usage_stats.ts index f19ec804ac6e9..28198c853e4b5 100644 --- a/src/plugins/telemetry/server/routes/telemetry_usage_stats.ts +++ b/src/plugins/telemetry/server/routes/telemetry_usage_stats.ts @@ -97,6 +97,30 @@ export function registerTelemetryUsageStatsRoutes( enableQueryVersion: true, // Allow specifying the version through querystring so that we can use it in Dev Console }) // Just because it used to be /v2/, we are creating identical v1 and v2. - .addVersion({ version: '1', validate: v2Validations }, v2Handler) - .addVersion({ version: '2', validate: v2Validations }, v2Handler); + .addVersion( + { + version: '1', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: v2Validations, + }, + v2Handler + ) + .addVersion( + { + version: '2', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: v2Validations, + }, + v2Handler + ); } diff --git a/src/plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts b/src/plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts index 54eaae80648ef..dff8a8f2d5bd4 100644 --- a/src/plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts +++ b/src/plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts @@ -56,6 +56,30 @@ export function registerTelemetryUserHasSeenNotice(router: IRouter, currentKiban router.versioned .put({ access: 'internal', path: UserHasSeenNoticeRoute }) // Just because it used to be /v2/, we are creating identical v1 and v2. - .addVersion({ version: '1', validate: false }, v2Handler) - .addVersion({ version: '2', validate: false }, v2Handler); + .addVersion( + { + version: '1', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: false, + }, + v2Handler + ) + .addVersion( + { + version: '2', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: false, + }, + v2Handler + ); } diff --git a/src/plugins/usage_collection/server/routes/stats/stats.ts b/src/plugins/usage_collection/server/routes/stats/stats.ts index 95a82abbbf150..3a7683bb1c46d 100644 --- a/src/plugins/usage_collection/server/routes/stats/stats.ts +++ b/src/plugins/usage_collection/server/routes/stats/stats.ts @@ -54,6 +54,12 @@ export function registerStatsRoute({ router.get( { path: '/api/stats', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, options: { authRequired: !config.allowAnonymous, // The `api` tag ensures that unauthenticated calls receive a 401 rather than a 302 redirect to login page. diff --git a/src/plugins/usage_collection/server/routes/ui_counters.ts b/src/plugins/usage_collection/server/routes/ui_counters.ts index 2545afb7f90fc..fbeba04ac1901 100644 --- a/src/plugins/usage_collection/server/routes/ui_counters.ts +++ b/src/plugins/usage_collection/server/routes/ui_counters.ts @@ -21,6 +21,12 @@ export function registerUiCountersRoute( router.post( { path: '/api/ui_counters/_report', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { body: schema.object({ report: reportSchema, diff --git a/x-pack/plugins/cloud/server/routes/elasticsearch_routes.ts b/x-pack/plugins/cloud/server/routes/elasticsearch_routes.ts index 5cdc2f90559cc..d3a5c4bebf305 100644 --- a/x-pack/plugins/cloud/server/routes/elasticsearch_routes.ts +++ b/x-pack/plugins/cloud/server/routes/elasticsearch_routes.ts @@ -24,12 +24,24 @@ export function defineRoutes({ path: ELASTICSEARCH_CONFIG_ROUTE, access: 'internal', }) - .addVersion({ version: '1', validate: {} }, async (context, request, response) => { - const body: ElasticsearchConfigType = { - elasticsearch_url: elasticsearchUrl, - }; - return response.ok({ - body, - }); - }); + .addVersion( + { + version: '1', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: {}, + }, + async (context, request, response) => { + const body: ElasticsearchConfigType = { + elasticsearch_url: elasticsearchUrl, + }; + return response.ok({ + body, + }); + } + ); } diff --git a/x-pack/plugins/licensing/server/routes/feature_usage.ts b/x-pack/plugins/licensing/server/routes/feature_usage.ts index 33317ab09cb9d..acb3303834de3 100644 --- a/x-pack/plugins/licensing/server/routes/feature_usage.ts +++ b/x-pack/plugins/licensing/server/routes/feature_usage.ts @@ -14,7 +14,16 @@ export function registerFeatureUsageRoute( getStartServices: StartServicesAccessor<{}, LicensingPluginStart> ) { router.get( - { path: '/api/licensing/feature_usage', validate: false }, + { + path: '/api/licensing/feature_usage', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: false, + }, async (context, request, response) => { const [, , { featureUsage }] = await getStartServices(); return response.ok({ diff --git a/x-pack/plugins/licensing/server/routes/info.ts b/x-pack/plugins/licensing/server/routes/info.ts index 1cbc7b6398966..c73508fac8236 100644 --- a/x-pack/plugins/licensing/server/routes/info.ts +++ b/x-pack/plugins/licensing/server/routes/info.ts @@ -9,7 +9,16 @@ import { LicensingRouter } from '../types'; export function registerInfoRoute(router: LicensingRouter) { router.get( - { path: '/api/licensing/info', validate: false }, + { + path: '/api/licensing/info', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, + validate: false, + }, async (context, request, response) => { return response.ok({ body: (await context.licensing).license, diff --git a/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts b/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts index a33cf4284245d..c3c70243005e2 100644 --- a/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts +++ b/x-pack/plugins/licensing/server/routes/internal/notify_feature_usage.ts @@ -12,6 +12,12 @@ export function registerNotifyFeatureUsageRoute(router: LicensingRouter) { router.post( { path: '/internal/licensing/feature_usage/notify', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { body: schema.object({ featureName: schema.string(), diff --git a/x-pack/plugins/licensing/server/routes/internal/register_feature.ts b/x-pack/plugins/licensing/server/routes/internal/register_feature.ts index 0c043c7c127a9..6b35c32a266d3 100644 --- a/x-pack/plugins/licensing/server/routes/internal/register_feature.ts +++ b/x-pack/plugins/licensing/server/routes/internal/register_feature.ts @@ -17,6 +17,12 @@ export function registerRegisterFeatureRoute( router.post( { path: '/internal/licensing/feature_usage/register', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { body: schema.arrayOf( schema.object({ From 73694426f943f00f74556406dcb26c66eb4a772a Mon Sep 17 00:00:00 2001 From: mohamedhamed-ahmed Date: Tue, 12 Nov 2024 12:26:36 +0000 Subject: [PATCH 020/105] [Discover] Breakdown support for fieldstats (#199028) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes https://github.com/elastic/kibana/issues/192700 ## 📝 Summary This PR add a new `Add breakdown` button to the field stats popover for all applicable fields. ## 🎥 Demo https://github.com/user-attachments/assets/d647189c-9b04-4127-a4fd-f9764babe46e --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-esql-utils/index.ts | 1 + packages/kbn-esql-utils/src/index.ts | 6 ++- .../src/utils/esql_fields_utils.test.ts | 49 ++++++++++++++++++- .../src/utils/esql_fields_utils.ts | 29 +++++++---- packages/kbn-field-utils/index.ts | 1 + .../utils/field_supports_breakdown.test.ts | 0 .../src}/utils/field_supports_breakdown.ts | 12 +++-- .../field_popover_header.test.tsx | 28 ++++++++++- .../field_popover/field_popover_header.tsx | 24 +++++++++ .../field_list_item.test.tsx | 36 ++++++++++++++ .../field_list_item.tsx | 17 +++++-- .../field_list_sidebar.tsx | 36 ++++++++------ packages/kbn-unified-field-list/tsconfig.json | 3 +- .../components/layout/discover_layout.tsx | 32 +++++++++--- .../discover_sidebar_responsive.test.tsx | 14 ++++++ .../sidebar/discover_sidebar_responsive.tsx | 28 ++++++----- .../public/chart/breakdown_field_selector.tsx | 8 ++- src/plugins/unified_histogram/public/index.ts | 1 - .../public/services/lens_vis_service.ts | 2 +- .../apps/discover/esql/_esql_view.ts | 17 +++++++ .../group1/_discover_histogram_breakdown.ts | 10 +++- .../page_objects/unified_field_list.ts | 10 ++++ .../public/hooks/use_degraded_docs_chart.ts | 2 +- .../dataset_quality/tsconfig.json | 3 +- 24 files changed, 307 insertions(+), 62 deletions(-) rename {src/plugins/unified_histogram/public => packages/kbn-field-utils/src}/utils/field_supports_breakdown.test.ts (100%) rename {src/plugins/unified_histogram/public => packages/kbn-field-utils/src}/utils/field_supports_breakdown.ts (65%) diff --git a/packages/kbn-esql-utils/index.ts b/packages/kbn-esql-utils/index.ts index ee47c0321e2e3..9519e84624cbe 100644 --- a/packages/kbn-esql-utils/index.ts +++ b/packages/kbn-esql-utils/index.ts @@ -31,6 +31,7 @@ export { getQueryColumnsFromESQLQuery, isESQLColumnSortable, isESQLColumnGroupable, + isESQLFieldGroupable, TextBasedLanguages, } from './src'; diff --git a/packages/kbn-esql-utils/src/index.ts b/packages/kbn-esql-utils/src/index.ts index cf530be20d7ae..6cf2dd031bf07 100644 --- a/packages/kbn-esql-utils/src/index.ts +++ b/packages/kbn-esql-utils/src/index.ts @@ -31,4 +31,8 @@ export { getStartEndParams, hasStartEndParams, } from './utils/run_query'; -export { isESQLColumnSortable, isESQLColumnGroupable } from './utils/esql_fields_utils'; +export { + isESQLColumnSortable, + isESQLColumnGroupable, + isESQLFieldGroupable, +} from './utils/esql_fields_utils'; diff --git a/packages/kbn-esql-utils/src/utils/esql_fields_utils.test.ts b/packages/kbn-esql-utils/src/utils/esql_fields_utils.test.ts index bfc3a4d6708f0..5bf9980d4ae78 100644 --- a/packages/kbn-esql-utils/src/utils/esql_fields_utils.test.ts +++ b/packages/kbn-esql-utils/src/utils/esql_fields_utils.test.ts @@ -7,7 +7,12 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ import type { DatatableColumn } from '@kbn/expressions-plugin/common'; -import { isESQLColumnSortable, isESQLColumnGroupable } from './esql_fields_utils'; +import { + isESQLColumnSortable, + isESQLColumnGroupable, + isESQLFieldGroupable, +} from './esql_fields_utils'; +import type { FieldSpec } from '@kbn/data-views-plugin/common'; describe('esql fields helpers', () => { describe('isESQLColumnSortable', () => { @@ -104,4 +109,46 @@ describe('esql fields helpers', () => { expect(isESQLColumnGroupable(keywordField)).toBeTruthy(); }); }); + + describe('isESQLFieldGroupable', () => { + it('returns false for unsupported fields', () => { + const fieldSpec: FieldSpec = { + name: 'unsupported', + type: 'unknown', + esTypes: ['unknown'], + searchable: true, + aggregatable: false, + isNull: false, + }; + + expect(isESQLFieldGroupable(fieldSpec)).toBeFalsy(); + }); + + it('returns false for counter fields', () => { + const fieldSpec: FieldSpec = { + name: 'tsbd_counter', + type: 'number', + esTypes: ['long'], + timeSeriesMetric: 'counter', + searchable: true, + aggregatable: false, + isNull: false, + }; + + expect(isESQLFieldGroupable(fieldSpec)).toBeFalsy(); + }); + + it('returns true for everything else', () => { + const fieldSpec: FieldSpec = { + name: 'sortable', + type: 'string', + esTypes: ['keyword'], + searchable: true, + aggregatable: false, + isNull: false, + }; + + expect(isESQLFieldGroupable(fieldSpec)).toBeTruthy(); + }); + }); }); diff --git a/packages/kbn-esql-utils/src/utils/esql_fields_utils.ts b/packages/kbn-esql-utils/src/utils/esql_fields_utils.ts index e2c5c785f8f58..fa0ae534197f6 100644 --- a/packages/kbn-esql-utils/src/utils/esql_fields_utils.ts +++ b/packages/kbn-esql-utils/src/utils/esql_fields_utils.ts @@ -7,6 +7,7 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ +import type { FieldSpec } from '@kbn/data-views-plugin/common'; import type { DatatableColumn } from '@kbn/expressions-plugin/common'; const SPATIAL_FIELDS = ['geo_point', 'geo_shape', 'point', 'shape']; @@ -40,22 +41,30 @@ export const isESQLColumnSortable = (column: DatatableColumn): boolean => { return true; }; +// Helper function to check if a field is groupable based on its type and esType +const isGroupable = (type: string | undefined, esType: string | undefined): boolean => { + // we don't allow grouping on the unknown field types + if (type === UNKNOWN_FIELD) { + return false; + } + // we don't allow grouping on tsdb counter fields + if (esType && esType.indexOf(TSDB_COUNTER_FIELDS_PREFIX) !== -1) { + return false; + } + return true; +}; + /** * Check if a column is groupable (| STATS ... BY ). * * @param column The DatatableColumn of the field. * @returns True if the column is groupable, false otherwise. */ - export const isESQLColumnGroupable = (column: DatatableColumn): boolean => { - // we don't allow grouping on the unknown field types - if (column.meta?.type === UNKNOWN_FIELD) { - return false; - } - // we don't allow grouping on tsdb counter fields - if (column.meta?.esType && column.meta?.esType?.indexOf(TSDB_COUNTER_FIELDS_PREFIX) !== -1) { - return false; - } + return isGroupable(column.meta?.type, column.meta?.esType); +}; - return true; +export const isESQLFieldGroupable = (field: FieldSpec): boolean => { + if (field.timeSeriesMetric === 'counter') return false; + return isGroupable(field.type, field.esTypes?.[0]); }; diff --git a/packages/kbn-field-utils/index.ts b/packages/kbn-field-utils/index.ts index ae77f0d1524fd..d3ce774177dcc 100644 --- a/packages/kbn-field-utils/index.ts +++ b/packages/kbn-field-utils/index.ts @@ -25,6 +25,7 @@ export { comboBoxFieldOptionMatcher, getFieldSearchMatchingHighlight, } from './src/utils/field_name_wildcard_matcher'; +export { fieldSupportsBreakdown } from './src/utils/field_supports_breakdown'; export { FieldIcon, type FieldIconProps, getFieldIconProps } from './src/components/field_icon'; export { FieldDescription, type FieldDescriptionProps } from './src/components/field_description'; diff --git a/src/plugins/unified_histogram/public/utils/field_supports_breakdown.test.ts b/packages/kbn-field-utils/src/utils/field_supports_breakdown.test.ts similarity index 100% rename from src/plugins/unified_histogram/public/utils/field_supports_breakdown.test.ts rename to packages/kbn-field-utils/src/utils/field_supports_breakdown.test.ts diff --git a/src/plugins/unified_histogram/public/utils/field_supports_breakdown.ts b/packages/kbn-field-utils/src/utils/field_supports_breakdown.ts similarity index 65% rename from src/plugins/unified_histogram/public/utils/field_supports_breakdown.ts rename to packages/kbn-field-utils/src/utils/field_supports_breakdown.ts index 12fdfbf20aa3b..3177d40012b57 100644 --- a/src/plugins/unified_histogram/public/utils/field_supports_breakdown.ts +++ b/packages/kbn-field-utils/src/utils/field_supports_breakdown.ts @@ -7,12 +7,18 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { DataViewField } from '@kbn/data-views-plugin/public'; +import { type DataViewField } from '@kbn/data-views-plugin/common'; +import { KNOWN_FIELD_TYPES } from './field_types'; -const supportedTypes = new Set(['string', 'boolean', 'number', 'ip']); +const supportedTypes = new Set([ + KNOWN_FIELD_TYPES.STRING, + KNOWN_FIELD_TYPES.BOOLEAN, + KNOWN_FIELD_TYPES.NUMBER, + KNOWN_FIELD_TYPES.IP, +]); export const fieldSupportsBreakdown = (field: DataViewField) => - supportedTypes.has(field.type) && + supportedTypes.has(field.type as KNOWN_FIELD_TYPES) && field.aggregatable && !field.scripted && field.timeSeriesMetric !== 'counter'; diff --git a/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.test.tsx b/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.test.tsx index 19fee33bc6eaf..a4e322f2b681c 100644 --- a/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.test.tsx +++ b/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.test.tsx @@ -38,6 +38,7 @@ describe('UnifiedFieldList ', () => { field={field} closePopover={mockClose} onAddFieldToWorkspace={jest.fn()} + onAddBreakdownField={jest.fn()} onAddFilter={jest.fn()} onEditField={jest.fn()} onDeleteField={jest.fn()} @@ -45,6 +46,9 @@ describe('UnifiedFieldList ', () => { ); expect(wrapper.text()).toBe(fieldName); + expect( + wrapper.find(`[data-test-subj="fieldPopoverHeader_addBreakdownField-${fieldName}"]`).exists() + ).toBeTruthy(); expect( wrapper.find(`[data-test-subj="fieldPopoverHeader_addField-${fieldName}"]`).exists() ).toBeTruthy(); @@ -57,7 +61,29 @@ describe('UnifiedFieldList ', () => { expect( wrapper.find(`[data-test-subj="fieldPopoverHeader_deleteField-${fieldName}"]`).exists() ).toBeTruthy(); - expect(wrapper.find(EuiButtonIcon)).toHaveLength(4); + expect(wrapper.find(EuiButtonIcon)).toHaveLength(5); + }); + + it('should correctly handle add-breakdown-field action', async () => { + const mockClose = jest.fn(); + const mockAddBreakdownField = jest.fn(); + const fieldName = 'extension'; + const field = dataView.fields.find((f) => f.name === fieldName)!; + const wrapper = mountWithIntl( + + ); + + wrapper + .find(`[data-test-subj="fieldPopoverHeader_addBreakdownField-${fieldName}"]`) + .first() + .simulate('click'); + + expect(mockClose).toHaveBeenCalled(); + expect(mockAddBreakdownField).toHaveBeenCalledWith(field); }); it('should correctly handle add-field action', async () => { diff --git a/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.tsx b/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.tsx index 65d5a1da98034..3babd05871913 100644 --- a/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.tsx +++ b/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.tsx @@ -31,6 +31,7 @@ export interface FieldPopoverHeaderProps { buttonAddFilterProps?: Partial; buttonEditFieldProps?: Partial; buttonDeleteFieldProps?: Partial; + onAddBreakdownField?: (field: DataViewField | undefined) => void; onAddFieldToWorkspace?: (field: DataViewField) => unknown; onAddFilter?: AddFieldFilterHandler; onEditField?: (fieldName: string) => unknown; @@ -47,6 +48,7 @@ export const FieldPopoverHeader: React.FC = ({ buttonAddFilterProps, buttonEditFieldProps, buttonDeleteFieldProps, + onAddBreakdownField, onAddFieldToWorkspace, onAddFilter, onEditField, @@ -82,6 +84,13 @@ export const FieldPopoverHeader: React.FC = ({ defaultMessage: 'Delete data view field', }); + const addBreakdownFieldTooltip = i18n.translate( + 'unifiedFieldList.fieldPopover.addBreakdownFieldLabel', + { + defaultMessage: 'Add breakdown', + } + ); + return ( <> @@ -108,6 +117,21 @@ export const FieldPopoverHeader: React.FC = ({ )} + {onAddBreakdownField && ( + + + { + closePopover(); + onAddBreakdownField(field); + }} + /> + + + )} {onAddFilter && field.filterable && !field.scripted && ( diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.test.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.test.tsx index a5b1955aeca2e..671a4175ad10a 100644 --- a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.test.tsx +++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.test.tsx @@ -43,10 +43,12 @@ async function getComponent({ selected = false, field, canFilter = true, + isBreakdownSupported = true, }: { selected?: boolean; field?: DataViewField; canFilter?: boolean; + isBreakdownSupported?: boolean; }) { const finalField = field ?? @@ -76,6 +78,7 @@ async function getComponent({ dataView: stubDataView, field: finalField, ...(canFilter && { onAddFilter: jest.fn() }), + ...(isBreakdownSupported && { onAddBreakdownField: jest.fn() }), onAddFieldToWorkspace: jest.fn(), onRemoveFieldFromWorkspace: jest.fn(), onEditField: jest.fn(), @@ -137,6 +140,34 @@ describe('UnifiedFieldListItem', function () { expect(comp.find(FieldItemButton).prop('onClick')).toBeUndefined(); }); + + it('should not show addBreakdownField action button if not supported', async function () { + const field = new DataViewField({ + name: 'extension.keyword', + type: 'string', + esTypes: ['keyword'], + aggregatable: true, + searchable: true, + }); + const { comp } = await getComponent({ + field, + isBreakdownSupported: false, + }); + + await act(async () => { + const fieldItem = findTestSubject(comp, 'field-extension.keyword-showDetails'); + await fieldItem.simulate('click'); + await comp.update(); + }); + + await comp.update(); + + expect( + comp + .find('[data-test-subj="fieldPopoverHeader_addBreakdownField-extension.keyword"]') + .exists() + ).toBeFalsy(); + }); it('should request field stats', async function () { const field = new DataViewField({ name: 'machine.os.raw', @@ -189,6 +220,11 @@ describe('UnifiedFieldListItem', function () { await comp.update(); expect(comp.find(EuiPopover).prop('isOpen')).toBe(true); + expect( + comp + .find('[data-test-subj="fieldPopoverHeader_addBreakdownField-extension.keyword"]') + .exists() + ).toBeTruthy(); expect( comp.find('[data-test-subj="fieldPopoverHeader_addField-extension.keyword"]').exists() ).toBeTruthy(); diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx index b139e7b5685c5..2ff7d22de39da 100644 --- a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx +++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx @@ -15,6 +15,8 @@ import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/publ import { Draggable } from '@kbn/dom-drag-drop'; import type { DataView, DataViewField } from '@kbn/data-views-plugin/public'; import { Filter } from '@kbn/es-query'; +import { fieldSupportsBreakdown } from '@kbn/field-utils'; +import { isESQLFieldGroupable } from '@kbn/esql-utils'; import type { SearchMode } from '../../types'; import { FieldItemButton, type FieldItemButtonProps } from '../../components/field_item_button'; import { @@ -140,6 +142,10 @@ export interface UnifiedFieldListItemProps { * The currently selected data view */ dataView: DataView; + /** + * Callback to update breakdown field + */ + onAddBreakdownField?: (breakdownField: DataViewField | undefined) => void; /** * Callback to add/select the field */ @@ -215,6 +221,7 @@ function UnifiedFieldListItemComponent({ field, highlight, dataView, + onAddBreakdownField, onAddFieldToWorkspace, onRemoveFieldFromWorkspace, onAddFilter, @@ -232,6 +239,9 @@ function UnifiedFieldListItemComponent({ }: UnifiedFieldListItemProps) { const [infoIsOpen, setOpen] = useState(false); + const isBreakdownSupported = + searchMode === 'documents' ? fieldSupportsBreakdown(field) : isESQLFieldGroupable(field); + const addFilterAndClosePopover: typeof onAddFilter | undefined = useMemo( () => onAddFilter @@ -394,13 +404,14 @@ function UnifiedFieldListItemComponent({ data-test-subj={stateService.creationOptions.dataTestSubj?.fieldListItemPopoverDataTestSubj} renderHeader={() => ( )} diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx index a7d8fb4616cb0..2d23903c34ea3 100644 --- a/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx +++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_sidebar/field_list_sidebar.tsx @@ -48,6 +48,7 @@ export type UnifiedFieldListSidebarCustomizableProps = Pick< | 'dataView' | 'trackUiMetric' | 'onAddFilter' + | 'onAddBreakdownField' | 'onAddFieldToWorkspace' | 'onRemoveFieldFromWorkspace' | 'additionalFilters' @@ -161,6 +162,7 @@ export const UnifiedFieldListSidebarComponent: React.FC (
  • ), @@ -298,6 +301,7 @@ export const UnifiedFieldListSidebarComponent: React.FC + isOfAggregateQueryType(query) + ? dataView?.isTimeBased() && !hasTransformationalCommand(query.esql) + : true, + [dataView, query] + ); + + const onAddBreakdownField = useCallback( + (field: DataViewField | undefined) => { + stateContainer.appState.update({ breakdownField: field?.name }); + }, + [stateContainer] + ); + const onFieldEdited = useCallback( async ({ removedFieldName }: { removedFieldName?: string } = {}) => { if (removedFieldName && currentColumns.includes(removedFieldName)) { @@ -423,18 +438,19 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) { sidebarToggleState$={sidebarToggleState$} sidebarPanel={ } mainPanel={ diff --git a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx index 6147bb916dad4..296d403da6901 100644 --- a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.test.tsx @@ -162,6 +162,7 @@ function getCompProps(options?: { hits?: DataTableRecord[] }): DiscoverSidebarRe result: hits, }) as DataDocuments$, onChangeDataView: jest.fn(), + onAddBreakdownField: jest.fn(), onAddFilter: jest.fn(), onAddField: jest.fn(), onRemoveField: jest.fn(), @@ -397,6 +398,19 @@ describe('discover responsive sidebar', function () { expect(ExistingFieldsServiceApi.loadFieldExisting).not.toHaveBeenCalled(); }); + it('should allow adding breakdown field', async function () { + const comp = await mountComponent(props); + const availableFields = findTestSubject(comp, 'fieldListGroupedAvailableFields'); + await act(async () => { + const button = findTestSubject(availableFields, 'field-extension-showDetails'); + button.simulate('click'); + comp.update(); + }); + + comp.update(); + findTestSubject(comp, 'fieldPopoverHeader_addBreakdownField-extension').simulate('click'); + expect(props.onAddBreakdownField).toHaveBeenCalled(); + }); it('should allow selecting fields', async function () { const comp = await mountComponent(props); const availableFields = findTestSubject(comp, 'fieldListGroupedAvailableFields'); diff --git a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx index 80a3b9d412c76..17a3e9def8b23 100644 --- a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx @@ -87,6 +87,10 @@ export interface DiscoverSidebarResponsiveProps { * hits fetched from ES, displayed in the doc table */ documents$: DataDocuments$; + /** + * Callback to update breakdown field + */ + onAddBreakdownField?: (breakdownField: DataViewField | undefined) => void; /** * Callback function when selecting a field */ @@ -151,6 +155,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) selectedDataView, columns, trackUiMetric, + onAddBreakdownField, onAddFilter, onFieldEdited, onDataViewCreated, @@ -373,23 +378,24 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) {selectedDataView ? ( ) : null} diff --git a/src/plugins/unified_histogram/public/chart/breakdown_field_selector.tsx b/src/plugins/unified_histogram/public/chart/breakdown_field_selector.tsx index 0d6aa1e75fe80..418892bd5434f 100644 --- a/src/plugins/unified_histogram/public/chart/breakdown_field_selector.tsx +++ b/src/plugins/unified_histogram/public/chart/breakdown_field_selector.tsx @@ -9,7 +9,12 @@ import React, { useCallback, useMemo } from 'react'; import { EuiSelectableOption } from '@elastic/eui'; -import { FieldIcon, getFieldIconProps, comboBoxFieldOptionMatcher } from '@kbn/field-utils'; +import { + FieldIcon, + getFieldIconProps, + comboBoxFieldOptionMatcher, + fieldSupportsBreakdown, +} from '@kbn/field-utils'; import { css } from '@emotion/react'; import { isESQLColumnGroupable } from '@kbn/esql-utils'; import { type DataView, DataViewField } from '@kbn/data-views-plugin/common'; @@ -17,7 +22,6 @@ import type { DatatableColumn } from '@kbn/expressions-plugin/common'; import { convertDatatableColumnToDataViewFieldSpec } from '@kbn/data-view-utils'; import { i18n } from '@kbn/i18n'; import { UnifiedHistogramBreakdownContext } from '../types'; -import { fieldSupportsBreakdown } from '../utils/field_supports_breakdown'; import { ToolbarSelector, ToolbarSelectorProps, diff --git a/src/plugins/unified_histogram/public/index.ts b/src/plugins/unified_histogram/public/index.ts index fda59c78819da..f79db6ce8a51a 100644 --- a/src/plugins/unified_histogram/public/index.ts +++ b/src/plugins/unified_histogram/public/index.ts @@ -36,6 +36,5 @@ export type { } from './types'; export { UnifiedHistogramFetchStatus, UnifiedHistogramExternalVisContextStatus } from './types'; export { canImportVisContext } from './utils/external_vis_context'; -export { fieldSupportsBreakdown } from './utils/field_supports_breakdown'; export const plugin = () => new UnifiedHistogramPublicPlugin(); diff --git a/src/plugins/unified_histogram/public/services/lens_vis_service.ts b/src/plugins/unified_histogram/public/services/lens_vis_service.ts index 2367e729b5a70..04bf810848f29 100644 --- a/src/plugins/unified_histogram/public/services/lens_vis_service.ts +++ b/src/plugins/unified_histogram/public/services/lens_vis_service.ts @@ -36,6 +36,7 @@ import { LegendSize } from '@kbn/visualizations-plugin/public'; import { XYConfiguration } from '@kbn/visualizations-plugin/common'; import type { Datatable, DatatableColumn } from '@kbn/expressions-plugin/common'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import { fieldSupportsBreakdown } from '@kbn/field-utils'; import { UnifiedHistogramExternalVisContextStatus, UnifiedHistogramSuggestionContext, @@ -49,7 +50,6 @@ import { injectESQLQueryIntoLensLayers, } from '../utils/external_vis_context'; import { computeInterval } from '../utils/compute_interval'; -import { fieldSupportsBreakdown } from '../utils/field_supports_breakdown'; import { shouldDisplayHistogram } from '../layout/helpers'; import { enrichLensAttributesWithTablesData } from '../utils/lens_vis_from_table'; diff --git a/test/functional/apps/discover/esql/_esql_view.ts b/test/functional/apps/discover/esql/_esql_view.ts index 272de320d2051..18841d07dac3d 100644 --- a/test/functional/apps/discover/esql/_esql_view.ts +++ b/test/functional/apps/discover/esql/_esql_view.ts @@ -843,6 +843,23 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const list = await discover.getHistogramLegendList(); expect(list).to.eql(['css', 'gif', 'jpg', 'php', 'png']); }); + + it('should choose breakdown field when selected from field stats', async () => { + await discover.selectTextBaseLang(); + await header.waitUntilLoadingHasFinished(); + await discover.waitUntilSearchingHasFinished(); + + const testQuery = 'from logstash-*'; + await monacoEditor.setCodeEditorValue(testQuery); + await testSubjects.click('querySubmitButton'); + await header.waitUntilLoadingHasFinished(); + await discover.waitUntilSearchingHasFinished(); + + await unifiedFieldList.clickFieldListAddBreakdownField('extension'); + await header.waitUntilLoadingHasFinished(); + const list = await discover.getHistogramLegendList(); + expect(list).to.eql(['css', 'gif', 'jpg', 'php', 'png']); + }); }); }); } diff --git a/test/functional/apps/discover/group1/_discover_histogram_breakdown.ts b/test/functional/apps/discover/group1/_discover_histogram_breakdown.ts index 5ce8732e5355a..6f04a6df1b6b4 100644 --- a/test/functional/apps/discover/group1/_discover_histogram_breakdown.ts +++ b/test/functional/apps/discover/group1/_discover_histogram_breakdown.ts @@ -14,11 +14,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const filterBar = getService('filterBar'); - const { common, discover, header, timePicker } = getPageObjects([ + const { common, discover, header, timePicker, unifiedFieldList } = getPageObjects([ 'common', 'discover', 'header', 'timePicker', + 'unifiedFieldList', ]); describe('discover unified histogram breakdown', function describeIndexTests() { @@ -36,6 +37,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); }); + it('should apply breakdown when selected from field stats', async () => { + await unifiedFieldList.clickFieldListAddBreakdownField('geo.dest'); + await header.waitUntilLoadingHasFinished(); + const list = await discover.getHistogramLegendList(); + expect(list).to.eql(['CN', 'IN', 'US', 'Other']); + }); + it('should choose breakdown field', async () => { await discover.chooseBreakdownField('extension.raw'); await header.waitUntilLoadingHasFinished(); diff --git a/test/functional/page_objects/unified_field_list.ts b/test/functional/page_objects/unified_field_list.ts index 14006c8c5d62e..4751769f717bd 100644 --- a/test/functional/page_objects/unified_field_list.ts +++ b/test/functional/page_objects/unified_field_list.ts @@ -226,6 +226,16 @@ export class UnifiedFieldListPageObject extends FtrService { await this.testSubjects.missingOrFail(`fieldVisualize-${field}`); } + public async clickFieldListAddBreakdownField(field: string) { + const addBreakdownFieldTestSubj = `fieldPopoverHeader_addBreakdownField-${field}`; + if (!(await this.testSubjects.exists(addBreakdownFieldTestSubj))) { + // field has to be open + await this.clickFieldListItem(field); + } + await this.testSubjects.click(addBreakdownFieldTestSubj); + await this.header.waitUntilLoadingHasFinished(); + } + public async clickFieldListPlusFilter(field: string, value: string) { const plusFilterTestSubj = `plus-${field}-${value}`; if (!(await this.testSubjects.exists(plusFilterTestSubj))) { diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_docs_chart.ts b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_docs_chart.ts index d3fad141335de..90779613f0c06 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_docs_chart.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/public/hooks/use_degraded_docs_chart.ts @@ -7,10 +7,10 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import type { Action } from '@kbn/ui-actions-plugin/public'; -import { fieldSupportsBreakdown } from '@kbn/unified-histogram-plugin/public'; import { i18n } from '@kbn/i18n'; import { useEuiTheme } from '@elastic/eui'; import type { DataView, DataViewField } from '@kbn/data-views-plugin/common'; +import { fieldSupportsBreakdown } from '@kbn/field-utils'; import { DEFAULT_LOGS_DATA_VIEW } from '../../common/constants'; import { useCreateDataView } from './use_create_dataview'; import { useKibanaContextForPlugin } from '../utils'; diff --git a/x-pack/plugins/observability_solution/dataset_quality/tsconfig.json b/x-pack/plugins/observability_solution/dataset_quality/tsconfig.json index f0d82fadb54ad..8576b08bd9479 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/tsconfig.json +++ b/x-pack/plugins/observability_solution/dataset_quality/tsconfig.json @@ -60,7 +60,8 @@ "@kbn/usage-collection-plugin", "@kbn/rison", "@kbn/task-manager-plugin", - "@kbn/core-application-browser" + "@kbn/core-application-browser", + "@kbn/field-utils" ], "exclude": [ "target/**/*" From 627692c4ef0c19d27f67c416ec206c374722fbac Mon Sep 17 00:00:00 2001 From: Kate Sosedova <36230123+ek-so@users.noreply.github.com> Date: Tue, 12 Nov 2024 13:32:51 +0100 Subject: [PATCH 021/105] =?UTF-8?q?Remove=20a=20condition=20to=20hide=20sp?= =?UTF-8?q?ace=20from=20dropdown=20menu=20even=20if=20there's=20o=E2=80=A6?= =?UTF-8?q?=20(#199601)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Based [on the issue](https://github.com/orgs/elastic/projects/1102/views/15?pane=issue&itemId=86718686&issue=elastic%7Ckibana%7C199594), I removed a condition to hide space from dropdown menu even if there's only one (for admins and regular users) - I also changed the wording from "Your spaces" to just "Spaces" so that we're consistent in all cases, [based on this comment](https://github.com/elastic/UX/issues/113#issuecomment-2464988675). --------- Co-authored-by: Elastic Machine --- .../spaces/public/nav_control/components/spaces_menu.tsx | 2 +- .../plugins/spaces/public/nav_control/nav_control_popover.tsx | 2 +- x-pack/plugins/translations/translations/fr-FR.json | 2 +- x-pack/plugins/translations/translations/zh-CN.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/spaces/public/nav_control/components/spaces_menu.tsx b/x-pack/plugins/spaces/public/nav_control/components/spaces_menu.tsx index 29d360fe91f3f..3a055fabd2cbf 100644 --- a/x-pack/plugins/spaces/public/nav_control/components/spaces_menu.tsx +++ b/x-pack/plugins/spaces/public/nav_control/components/spaces_menu.tsx @@ -117,7 +117,7 @@ class SpacesMenuUI extends Component { {search || i18n.translate('xpack.spaces.navControl.spacesMenu.selectSpacesTitle', { - defaultMessage: 'Your spaces', + defaultMessage: 'Spaces', })} {list} diff --git a/x-pack/plugins/spaces/public/nav_control/nav_control_popover.tsx b/x-pack/plugins/spaces/public/nav_control/nav_control_popover.tsx index cd08ff87e1a55..31a721e4b02ec 100644 --- a/x-pack/plugins/spaces/public/nav_control/nav_control_popover.tsx +++ b/x-pack/plugins/spaces/public/nav_control/nav_control_popover.tsx @@ -97,7 +97,7 @@ class NavControlPopoverUI extends Component { const isTourOpen = Boolean(activeSpace) && this.state.showTour && !this.state.showSpaceSelector; let element: React.ReactNode; - if (this.state.loading || this.state.spaces.length < 2) { + if (this.state.loading) { element = ( Date: Tue, 12 Nov 2024 12:49:51 +0000 Subject: [PATCH 022/105] [ObsUX][APM] Migrate error_rate tests to agnostic deployment tests (#199672) ### Summary Closes https://github.com/elastic/kibana/issues/198970 Part of https://github.com/elastic/kibana/issues/193245 This PR contains the changes to migrate error_rate test folder to Deployment-agnostic testing strategy. #### How to test Serverless ``` node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/serverless/oblt.serverless.config.ts --grep="APM" ``` It's recommended to be run against [MKI](https://github.com/crespocarlos/kibana/blob/main/x-pack/test_serverless/README.md#run-tests-on-mki) Stateful ``` node scripts/functional_tests_server --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts node scripts/functional_test_runner --config x-pack/test/api_integration/deployment_agnostic/configs/stateful/oblt.stateful.config.ts --grep="APM" ``` Checks - [ ] (OPTIONAL, only if a test has been unskipped) Run flaky test suite - [x] local run for serverless - [x] local run for stateful - [x] MKI run for serverless --- .../observability/apm/error_rate/index.ts | 15 ++++++++++ .../apm}/error_rate/service_apis.spec.ts | 26 +++++++++-------- .../apm}/error_rate/service_maps.spec.ts | 28 +++++++++++-------- .../apis/observability/apm/index.ts | 1 + 4 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/index.ts rename x-pack/test/{apm_api_integration/tests => api_integration/deployment_agnostic/apis/observability/apm}/error_rate/service_apis.spec.ts (93%) rename x-pack/test/{apm_api_integration/tests => api_integration/deployment_agnostic/apis/observability/apm}/error_rate/service_maps.spec.ts (89%) diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/index.ts new file mode 100644 index 0000000000000..a3dd89f0ddb1a --- /dev/null +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ loadTestFile }: DeploymentAgnosticFtrProviderContext) { + describe('error_rate', () => { + loadTestFile(require.resolve('./service_apis.spec.ts')); + loadTestFile(require.resolve('./service_maps.spec.ts')); + }); +} diff --git a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/service_apis.spec.ts similarity index 93% rename from x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts rename to x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/service_apis.spec.ts index 2ab6b1bb97a5e..56dded824a32d 100644 --- a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.spec.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/service_apis.spec.ts @@ -5,6 +5,7 @@ * 2.0. */ import { apm, timerange } from '@kbn/apm-synthtrace-client'; +import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; import expect from '@kbn/expect'; import { mean, meanBy, sumBy } from 'lodash'; import { LatencyAggregationType } from '@kbn/apm-plugin/common/latency_aggregation_types'; @@ -12,12 +13,16 @@ import { isFiniteNumber } from '@kbn/apm-plugin/common/utils/is_finite_number'; import { ApmDocumentType } from '@kbn/apm-plugin/common/document_type'; import { RollupInterval } from '@kbn/apm-plugin/common/rollup'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const apmApiClient = getService('apmApiClient'); - const apmSynthtraceEsClient = getService('apmSynthtraceEsClient'); +const GO_PROD_LIST_RATE = 75; +const GO_PROD_LIST_ERROR_RATE = 25; +const GO_PROD_ID_RATE = 50; +const GO_PROD_ID_ERROR_RATE = 50; + +export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { + const apmApiClient = getService('apmApi'); + const synthtrace = getService('synthtrace'); const serviceName = 'synth-go'; const start = new Date('2021-01-01T00:00:00.000Z').getTime(); @@ -151,13 +156,10 @@ export default function ApiTest({ getService }: FtrProviderContext) { let errorRateMetricValues: Awaited>; let errorTransactionValues: Awaited>; - // FLAKY: https://github.com/elastic/kibana/issues/177321 - registry.when('Services APIs', { config: 'basic', archives: [] }, () => { + describe('Services APIs', () => { describe('when data is loaded ', () => { - const GO_PROD_LIST_RATE = 75; - const GO_PROD_LIST_ERROR_RATE = 25; - const GO_PROD_ID_RATE = 50; - const GO_PROD_ID_ERROR_RATE = 50; + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + before(async () => { const serviceGoProdInstance = apm .service({ name: serviceName, environment: 'production', agentName: 'go' }) @@ -166,6 +168,8 @@ export default function ApiTest({ getService }: FtrProviderContext) { const transactionNameProductList = 'GET /api/product/list'; const transactionNameProductId = 'GET /api/product/:id'; + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); + await apmSynthtraceEsClient.index([ timerange(start, end) .interval('1m') diff --git a/x-pack/test/apm_api_integration/tests/error_rate/service_maps.spec.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/service_maps.spec.ts similarity index 89% rename from x-pack/test/apm_api_integration/tests/error_rate/service_maps.spec.ts rename to x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/service_maps.spec.ts index aa7d635b977cc..462ad8db4bdda 100644 --- a/x-pack/test/apm_api_integration/tests/error_rate/service_maps.spec.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/error_rate/service_maps.spec.ts @@ -5,17 +5,22 @@ * 2.0. */ import { apm, timerange } from '@kbn/apm-synthtrace-client'; +import { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; import expect from '@kbn/expect'; import { meanBy } from 'lodash'; import { ApmDocumentType } from '@kbn/apm-plugin/common/document_type'; import { RollupInterval } from '@kbn/apm-plugin/common/rollup'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { DeploymentAgnosticFtrProviderContext } from '../../../../ftr_provider_context'; -export default function ApiTest({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const apmApiClient = getService('apmApiClient'); - const apmSynthtraceEsClient = getService('apmSynthtraceEsClient'); +const GO_PROD_LIST_RATE = 75; +const GO_PROD_LIST_ERROR_RATE = 25; +const GO_PROD_ID_RATE = 50; +const GO_PROD_ID_ERROR_RATE = 50; + +export default function ApiTest({ getService }: DeploymentAgnosticFtrProviderContext) { + const apmApiClient = getService('apmApi'); + const synthtrace = getService('synthtrace'); const serviceName = 'synth-go'; const start = new Date('2021-01-01T00:00:00.000Z').getTime(); @@ -74,13 +79,11 @@ export default function ApiTest({ getService }: FtrProviderContext) { let errorRateMetricValues: Awaited>; let errorTransactionValues: Awaited>; - registry.when('Service Maps APIs', { config: 'trial', archives: [] }, () => { + + describe('Service Maps APIs', () => { describe('when data is loaded ', () => { - const GO_PROD_LIST_RATE = 75; - const GO_PROD_LIST_ERROR_RATE = 25; - const GO_PROD_ID_RATE = 50; - const GO_PROD_ID_ERROR_RATE = 50; - before(() => { + let apmSynthtraceEsClient: ApmSynthtraceEsClient; + before(async () => { const serviceGoProdInstance = apm .service({ name: serviceName, environment: 'production', agentName: 'go' }) .instance('instance-a'); @@ -88,6 +91,8 @@ export default function ApiTest({ getService }: FtrProviderContext) { const transactionNameProductList = 'GET /api/product/list'; const transactionNameProductId = 'GET /api/product/:id'; + apmSynthtraceEsClient = await synthtrace.createApmSynthtraceEsClient(); + return apmSynthtraceEsClient.index([ timerange(start, end) .interval('1m') @@ -140,7 +145,6 @@ export default function ApiTest({ getService }: FtrProviderContext) { after(() => apmSynthtraceEsClient.clean()); - // FLAKY: https://github.com/elastic/kibana/issues/172772 describe('compare latency value between service inventory and service maps', () => { before(async () => { [errorTransactionValues, errorRateMetricValues] = await Promise.all([ diff --git a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts index cc56d0f2e6684..a62386b536ea8 100644 --- a/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts +++ b/x-pack/test/api_integration/deployment_agnostic/apis/observability/apm/index.ts @@ -16,6 +16,7 @@ export default function apmApiIntegrationTests({ loadTestFile(require.resolve('./mobile')); loadTestFile(require.resolve('./custom_dashboards')); loadTestFile(require.resolve('./dependencies')); + loadTestFile(require.resolve('./error_rate')); loadTestFile(require.resolve('./data_view')); loadTestFile(require.resolve('./correlations')); loadTestFile(require.resolve('./entities')); From 9975c552da13e778b82ffa91d1a6fe1de8cac4a6 Mon Sep 17 00:00:00 2001 From: Marco Antonio Ghiani Date: Tue, 12 Nov 2024 14:25:09 +0100 Subject: [PATCH 023/105] [Logs] Deprecation warning for Logs Explorer and Logs Stream (#199652) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📓 Summary Closes https://github.com/elastic/observability-dev/issues/4070 - Update the deprecation callouts to suggest that the user use Discover. - Replace the beta badge in Logs Explorer with a deprecation notice. - Mark the advanced setting to enable the log stream to be deprecated. Screenshot 2024-11-11 at 15 22 51 --------- Co-authored-by: Marco Antonio Ghiani Co-authored-by: Mike Birnstiehl <114418652+mdbirnstiehl@users.noreply.github.com> --- .../infra/common/ui_settings.ts | 7 ++++ .../components/logs_deprecation_callout.tsx | 37 +++++++--------- .../common/translations.ts | 24 ++++++++--- .../components/logs_explorer_top_nav_menu.tsx | 42 +++++++++++-------- .../translations/translations/fr-FR.json | 5 --- .../translations/translations/ja-JP.json | 5 --- .../translations/translations/zh-CN.json | 5 --- 7 files changed, 64 insertions(+), 61 deletions(-) diff --git a/x-pack/plugins/observability_solution/infra/common/ui_settings.ts b/x-pack/plugins/observability_solution/infra/common/ui_settings.ts index 95f1ee0a44bae..9b85630761942 100644 --- a/x-pack/plugins/observability_solution/infra/common/ui_settings.ts +++ b/x-pack/plugins/observability_solution/infra/common/ui_settings.ts @@ -23,6 +23,13 @@ export const uiSettings: Record = { description: i18n.translate('xpack.infra.enableLogsStreamDescription', { defaultMessage: 'Enables the legacy Logs Stream application and dashboard panel. ', }), + deprecation: { + message: i18n.translate('xpack.infra.enableLogsStreamDeprecationWarning', { + defaultMessage: + 'Logs Stream is deprecated, and this setting will be removed in Kibana 9.0.', + }), + docLinksKey: 'generalSettings', + }, type: 'boolean', schema: schema.boolean(), requiresPageReload: true, diff --git a/x-pack/plugins/observability_solution/infra/public/components/logs_deprecation_callout.tsx b/x-pack/plugins/observability_solution/infra/public/components/logs_deprecation_callout.tsx index 21e61c08d281b..0edb8b9ab2924 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/logs_deprecation_callout.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/logs_deprecation_callout.tsx @@ -9,36 +9,28 @@ import { EuiCallOut } from '@elastic/eui'; import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButton } from '@elastic/eui'; -import { - AllDatasetsLocatorParams, - ALL_DATASETS_LOCATOR_ID, - DatasetLocatorParams, -} from '@kbn/deeplinks-observability'; import { getRouterLinkProps } from '@kbn/router-utils'; import useLocalStorage from 'react-use/lib/useLocalStorage'; - import { euiThemeVars } from '@kbn/ui-theme'; import { css } from '@emotion/css'; import { LocatorPublic } from '@kbn/share-plugin/common'; +import { DISCOVER_APP_LOCATOR, DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; import { useKibanaContextForPlugin } from '../hooks/use_kibana'; const pageConfigurations = { stream: { dismissalStorageKey: 'log_stream_deprecation_callout_dismissed', - message: i18n.translate('xpack.infra.logsDeprecationCallout.p.theNewLogsExplorerLabel', { + message: i18n.translate('xpack.infra.logsDeprecationCallout.stream.exploreWithDiscover', { defaultMessage: - 'The new Logs Explorer makes viewing and inspecting your logs easier with more features, better performance, and more intuitive navigation. We recommend switching to Logs Explorer, as it will replace Logs Stream in a future version.', + 'Logs Stream and Logs Explorer are set to be deprecated. Switch to Discover which now includes their functionality plus more features, better performance, and more intuitive navigation. ', }), }, settings: { dismissalStorageKey: 'log_settings_deprecation_callout_dismissed', - message: i18n.translate( - 'xpack.infra.logsSettingsDeprecationCallout.p.theNewLogsExplorerLabel', - { - defaultMessage: - 'These settings only apply to the legacy Logs Stream app, and we do not recommend configuring them. Instead, use Logs Explorer which makes viewing and inspecting your logs easier with more features, better performance, and more intuitive navigation.', - } - ), + message: i18n.translate('xpack.infra.logsDeprecationCallout.settings.exploreWithDiscover', { + defaultMessage: + 'These settings only apply to the legacy Logs Stream app. Switch to Discover for the same functionality plus more features, better performance, and more intuitive navigation.', + }), }, }; @@ -60,10 +52,9 @@ export const LogsDeprecationCallout = ({ page }: LogsDeprecationCalloutProps) => const [isDismissed, setDismissed] = useLocalStorage(dismissalStorageKey, false); - const allDatasetLocator = - share.url.locators.get(ALL_DATASETS_LOCATOR_ID); + const discoverLocator = share.url.locators.get(DISCOVER_APP_LOCATOR); - if (isDismissed || !(allDatasetLocator && discover?.show && fleet?.read)) { + if (isDismissed || !(discoverLocator && discover?.show && fleet?.read)) { return null; } @@ -81,19 +72,19 @@ export const LogsDeprecationCallout = ({ page }: LogsDeprecationCalloutProps) =>

    {message}

    - {i18n.translate('xpack.infra.logsDeprecationCallout.tryLogsExplorerButtonLabel', { - defaultMessage: 'Try Logs Explorer', + {i18n.translate('xpack.infra.logsDeprecationCallout.goToDiscoverButtonLabel', { + defaultMessage: 'Go to Discover', })} ); }; -const getLogsExplorerLinkProps = (locator: LocatorPublic) => { +const getDiscoverLinkProps = (locator: LocatorPublic) => { return getRouterLinkProps({ href: locator.getRedirectUrl({}), onClick: () => locator.navigate({}), diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/common/translations.ts b/x-pack/plugins/observability_solution/observability_logs_explorer/common/translations.ts index f89c6eb47e6c4..380bc3c3c5a26 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/common/translations.ts +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/common/translations.ts @@ -22,14 +22,26 @@ export const observabilityAppTitle = i18n.translate( } ); -export const betaBadgeTitle = i18n.translate('xpack.observabilityLogsExplorer.betaBadgeTitle', { - defaultMessage: 'Beta', -}); +export const deprecationBadgeTitle = i18n.translate( + 'xpack.observabilityLogsExplorer.deprecationBadgeTitle', + { + defaultMessage: 'Deprecation notice', + } +); + +export const deprecationBadgeDescription = i18n.translate( + 'xpack.observabilityLogsExplorer.deprecationBadgeDescription', + { + defaultMessage: + 'Logs Stream and Logs Explorer are set to be deprecated. Switch to Discover which now includes their functionality plus more features and better performance.', + } +); -export const betaBadgeDescription = i18n.translate( - 'xpack.observabilityLogsExplorer.betaBadgeDescription', +export const deprecationBadgeGuideline = i18n.translate( + 'xpack.observabilityLogsExplorer.deprecationBadgeGuideline', { - defaultMessage: 'This application is in beta and therefore subject to change.', + defaultMessage: + 'You can temporarily access Logs Stream by re-enabling it in Advanced Settings.', } ); diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/logs_explorer_top_nav_menu.tsx b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/logs_explorer_top_nav_menu.tsx index c3f91b3bf8660..0020df30b8708 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/logs_explorer_top_nav_menu.tsx +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/logs_explorer_top_nav_menu.tsx @@ -21,7 +21,11 @@ import { LogsExplorerTabs } from '@kbn/discover-plugin/public'; import React, { useEffect, useState } from 'react'; import useObservable from 'react-use/lib/useObservable'; import { filter, take } from 'rxjs'; -import { betaBadgeDescription, betaBadgeTitle } from '../../common/translations'; +import { + deprecationBadgeDescription, + deprecationBadgeGuideline, + deprecationBadgeTitle, +} from '../../common/translations'; import { useKibanaContextForPlugin } from '../utils/use_kibana'; import { ConnectedDiscoverLink } from './discover_link'; import { FeedbackLink } from './feedback_link'; @@ -59,13 +63,7 @@ const ProjectTopNav = () => { `} > - + @@ -115,15 +113,6 @@ const ClassicTopNav = () => { margin-left: ${euiThemeVars.euiSizeM}; `} > - - - @@ -145,6 +134,9 @@ const ClassicTopNav = () => { + + + @@ -171,3 +163,19 @@ const ConditionalVerticalRule = ({ Component }: { Component: JSX.Element | null {Component} ); + +const DeprecationNoticeBadge = () => ( + + {deprecationBadgeDescription} +
    +
    + {deprecationBadgeGuideline} + + } + alignment="middle" + /> +); diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 301635bbb9623..2a66c10a65093 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -24651,8 +24651,6 @@ "xpack.infra.logs.viewInContext.logsFromContainerTitle": "Les logs affichés proviennent du conteneur {container}", "xpack.infra.logs.viewInContext.logsFromFileTitle": "Les logs affichés proviennent du fichier {file} et de l'hôte {host}", "xpack.infra.logsDeprecationCallout.euiCallOut.discoverANewLogLabel": "Il existe une nouvelle (et meilleure) façon d'explorer vos logs !", - "xpack.infra.logsDeprecationCallout.p.theNewLogsExplorerLabel": "Le nouveau Logs Explorer facilite la visualisation et l'inspection de vos journaux et propose davantage de fonctionnalités, des performances supérieures ainsi qu’une navigation plus intuitive. Nous vous recommandons de passer à Logs Explorer, car il remplacera Logs Stream dans une version ultérieure.", - "xpack.infra.logsDeprecationCallout.tryLogsExplorerButtonLabel": "Essayer Logs Explorer", "xpack.infra.logsHeaderAddDataButtonLabel": "Ajouter des données", "xpack.infra.logSourceConfiguration.childFormElementErrorMessage": "L'état d'au moins un champ du formulaire est non valide.", "xpack.infra.logSourceConfiguration.dataViewDescription": "Vue de données contenant les données de log", @@ -24685,7 +24683,6 @@ "xpack.infra.logSourceErrorPage.tryAgainButtonLabel": "Réessayer", "xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder": "Recherche d'entrées de log… (par ex. host.name:host-1)", "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "Erreur de filtrage du log", - "xpack.infra.logsSettingsDeprecationCallout.p.theNewLogsExplorerLabel": "Ces paramètres s'appliquent uniquement à l'ancienne application Logs Stream et nous vous déconseillons de les configurer. Utilisez plutôt le nouveau Logs Explorer qui facilite la visualisation et l'inspection de vos logs et propose davantage de fonctionnalités, des performances supérieures ainsi qu'une navigation plus intuitive.", "xpack.infra.logsSettingsPage.loadingButtonLabel": "Chargement", "xpack.infra.logsStreamEmbeddable.deprecationWarningDescription": "La maintenance des panneaux de flux de logs n'est plus assurée. Essayez d'utiliser {savedSearchDocsLink} pour une visualisation similaire.", "xpack.infra.logsStreamEmbeddable.deprecationWarningDescription.savedSearchesLinkLabel": "recherches enregistrées", @@ -34658,8 +34655,6 @@ "xpack.observabilityLogsExplorer.alertsPopover.createSLOMenuItem": "Créer un SLO", "xpack.observabilityLogsExplorer.alertsPopover.manageRulesMenuItem": "{canCreateRule, select, true{Gérer} other{Afficher}} les règles", "xpack.observabilityLogsExplorer.appTitle": "Explorateur de logs", - "xpack.observabilityLogsExplorer.betaBadgeDescription": "Il s'agit du stade bêta de l'application, qui est donc susceptible d'évoluer.", - "xpack.observabilityLogsExplorer.betaBadgeTitle": "Bêta", "xpack.observabilityLogsExplorer.createSlo": "Créer un SLO", "xpack.observabilityLogsExplorer.datasetQualityLinkTitle": "Ensembles de données", "xpack.observabilityLogsExplorer.discoverLinkTitle": "Ouvrir dans Discover", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 17fb0b2ff933d..6ac1f1e800bf4 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -24625,8 +24625,6 @@ "xpack.infra.logs.viewInContext.logsFromContainerTitle": "表示されたログはコンテナー{container}から取得されました", "xpack.infra.logs.viewInContext.logsFromFileTitle": "表示されたログは、ファイル{file}およびホスト{host}から取得されました", "xpack.infra.logsDeprecationCallout.euiCallOut.discoverANewLogLabel": "ログの探索には、新しく、もっと効果的な方法があります。", - "xpack.infra.logsDeprecationCallout.p.theNewLogsExplorerLabel": "新しいログエクスプローラーには、追加機能、パフォーマンスの改善、さらに直感的なナビゲーションが導入され、ログの表示と調査がさらに簡単になりました。将来のバージョンでは、ログストリームに取って代わるため、ログエクスプローラーを使用することをお勧めします。", - "xpack.infra.logsDeprecationCallout.tryLogsExplorerButtonLabel": "ログエクスプローラーを試す", "xpack.infra.logsHeaderAddDataButtonLabel": "データの追加", "xpack.infra.logSourceConfiguration.childFormElementErrorMessage": "1つ以上のフォームフィールドが無効な状態です。", "xpack.infra.logSourceConfiguration.dataViewDescription": "ログデータを含むデータビュー", @@ -24658,7 +24656,6 @@ "xpack.infra.logSourceErrorPage.tryAgainButtonLabel": "再試行", "xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder": "ログエントリーを検索中…(例:host.name:host-1)", "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "ログフィルターエラー", - "xpack.infra.logsSettingsDeprecationCallout.p.theNewLogsExplorerLabel": "これらの設定はレガシーログストリームアプリにのみ適用されます。これらを構成することはお勧めしません。代わりに、新しいログエクスプローラーを使用してください。追加機能、パフォーマンスの改善、さらに直感的なナビゲーションが導入され、ログの表示と調査がさらに簡単になりました。", "xpack.infra.logsSettingsPage.loadingButtonLabel": "読み込み中", "xpack.infra.logsStreamEmbeddable.deprecationWarningDescription": "ログストリームパネルは管理されていません。{savedSearchDocsLink}を同様の視覚化に活用してください。", "xpack.infra.logsStreamEmbeddable.deprecationWarningDescription.savedSearchesLinkLabel": "保存された検索", @@ -34628,8 +34625,6 @@ "xpack.observabilityLogsExplorer.alertsPopover.createSLOMenuItem": "SLOの作成", "xpack.observabilityLogsExplorer.alertsPopover.manageRulesMenuItem": "ルールを{canCreateRule, select, true{管理} other{表示}}", "xpack.observabilityLogsExplorer.appTitle": "ログエクスプローラー", - "xpack.observabilityLogsExplorer.betaBadgeDescription": "このアプリケーションはベータ版であるため、変更される場合があります。", - "xpack.observabilityLogsExplorer.betaBadgeTitle": "ベータ", "xpack.observabilityLogsExplorer.createSlo": "SLOの作成", "xpack.observabilityLogsExplorer.datasetQualityLinkTitle": "データセット", "xpack.observabilityLogsExplorer.discoverLinkTitle": "Discoverで開く", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 4cb03c51d0572..787ddd9a45d48 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -24204,8 +24204,6 @@ "xpack.infra.logs.viewInContext.logsFromContainerTitle": "显示的日志来自容器 {container}", "xpack.infra.logs.viewInContext.logsFromFileTitle": "显示的日志来自文件 {file} 和主机 {host}", "xpack.infra.logsDeprecationCallout.euiCallOut.discoverANewLogLabel": "这是浏览日志的更有效的新方法!", - "xpack.infra.logsDeprecationCallout.p.theNewLogsExplorerLabel": "新的日志浏览器具有更多功能,更优异的性能和更直观的导航,便于您更轻松地查看和检查日志。建议您切换到日志浏览器,因为它将在未来版本中替代日志流。", - "xpack.infra.logsDeprecationCallout.tryLogsExplorerButtonLabel": "试用日志浏览器", "xpack.infra.logsHeaderAddDataButtonLabel": "添加数据", "xpack.infra.logSourceConfiguration.childFormElementErrorMessage": "至少一个表单字段处于无效状态。", "xpack.infra.logSourceConfiguration.dataViewDescription": "包含日志数据的数据视图", @@ -24236,7 +24234,6 @@ "xpack.infra.logSourceErrorPage.tryAgainButtonLabel": "重试", "xpack.infra.logsPage.toolbar.kqlSearchFieldPlaceholder": "搜索日志条目……(例如 host.name:host-1)", "xpack.infra.logsPage.toolbar.logFilterErrorToastTitle": "日志筛选错误", - "xpack.infra.logsSettingsDeprecationCallout.p.theNewLogsExplorerLabel": "这些设置仅适用于旧版日志流应用,不建议配置它们。相反,应使用具有更多功能,更优异的性能和更直观的导航,便于您更轻松地查看和检查日志的日志浏览器。", "xpack.infra.logsSettingsPage.loadingButtonLabel": "正在加载", "xpack.infra.logsStreamEmbeddable.deprecationWarningDescription": "将不再维护日志流面板。尝试将 {savedSearchDocsLink} 用于类似可视化。", "xpack.infra.logsStreamEmbeddable.deprecationWarningDescription.savedSearchesLinkLabel": "已保存的搜索", @@ -34107,8 +34104,6 @@ "xpack.observabilityLogsExplorer.alertsPopover.createSLOMenuItem": "创建 SLO", "xpack.observabilityLogsExplorer.alertsPopover.manageRulesMenuItem": "{canCreateRule, select, true{管理} other{查看}}规则", "xpack.observabilityLogsExplorer.appTitle": "日志浏览器", - "xpack.observabilityLogsExplorer.betaBadgeDescription": "此应用程序为公测版,因此可能会进行更改。", - "xpack.observabilityLogsExplorer.betaBadgeTitle": "公测版", "xpack.observabilityLogsExplorer.createSlo": "创建 SLO", "xpack.observabilityLogsExplorer.datasetQualityLinkTitle": "数据集", "xpack.observabilityLogsExplorer.discoverLinkTitle": "在 Discover 中打开", From 7e06f554363d2bf8fe5656062e34053284005943 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Tue, 12 Nov 2024 08:28:28 -0500 Subject: [PATCH 024/105] [Fleet] Fix install with streaming test (#199725) --- .../apis/epm/install_with_streaming.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_with_streaming.ts b/x-pack/test/fleet_api_integration/apis/epm/install_with_streaming.ts index 4fa0e485be2b5..95968cd519768 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_with_streaming.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_with_streaming.ts @@ -36,8 +36,7 @@ export default function (providerContext: FtrProviderContext) { return res?._source?.['epm-packages'] as Installation; }; - // Failing: See https://github.com/elastic/kibana/issues/199701 - describe.skip('Installs a package using stream-based approach', () => { + describe('Installs a package using stream-based approach', () => { skipIfNoDockerRegistry(providerContext); before(async () => { @@ -50,7 +49,8 @@ export default function (providerContext: FtrProviderContext) { await uninstallPackage('security_detection_engine', '8.16.0'); }); it('should install security-rule assets from the package', async () => { - await installPackage('security_detection_engine', '8.16.0').expect(200); + // Force install to install an outdatded version + await installPackage('security_detection_engine', '8.16.0', { force: true }).expect(200); const installationSO = await getInstallationSavedObject('security_detection_engine'); expect(installationSO?.installed_kibana).toEqual( expect.arrayContaining([ From f9e8aa07b79e6d81d691a4f166c04f74335fdf7f Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Tue, 12 Nov 2024 08:28:54 -0500 Subject: [PATCH 025/105] [Fleet] Change uninstall tokens space when changing agent policies spaces (#199536) --- .../fleet/server/services/app_context.ts | 1 + .../security/uninstall_token_service/index.ts | 2 +- .../services/spaces/agent_policy.test.ts | 28 ++++++++ .../server/services/spaces/agent_policy.ts | 22 ++++++ .../change_space_agent_policies.ts | 68 ++++++++++++------- 5 files changed, 95 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/app_context.ts b/x-pack/plugins/fleet/server/services/app_context.ts index 7dccb7ba1dfe0..da40f8ff7d819 100644 --- a/x-pack/plugins/fleet/server/services/app_context.ts +++ b/x-pack/plugins/fleet/server/services/app_context.ts @@ -240,6 +240,7 @@ class AppContextService { // soClient as kibana internal users, be careful on how you use it, security is not enabled return appContextService.getSavedObjects().getScopedClient(fakeRequest, { excludedExtensions: [SECURITY_EXTENSION_ID, SPACES_EXTENSION_ID], + includedHiddenTypes: [UNINSTALL_TOKENS_SAVED_OBJECT_TYPE], }); } diff --git a/x-pack/plugins/fleet/server/services/security/uninstall_token_service/index.ts b/x-pack/plugins/fleet/server/services/security/uninstall_token_service/index.ts index 0a44a3df0f294..1f58fcafd396b 100644 --- a/x-pack/plugins/fleet/server/services/security/uninstall_token_service/index.ts +++ b/x-pack/plugins/fleet/server/services/security/uninstall_token_service/index.ts @@ -46,7 +46,7 @@ import { appContextService } from '../../app_context'; import { agentPolicyService, getAgentPolicySavedObjectType } from '../../agent_policy'; import { isSpaceAwarenessEnabled } from '../../spaces/helpers'; -interface UninstallTokenSOAttributes { +export interface UninstallTokenSOAttributes { policy_id: string; token: string; token_plain: string; diff --git a/x-pack/plugins/fleet/server/services/spaces/agent_policy.test.ts b/x-pack/plugins/fleet/server/services/spaces/agent_policy.test.ts index ab69d4708c436..079148a6ae041 100644 --- a/x-pack/plugins/fleet/server/services/spaces/agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/spaces/agent_policy.test.ts @@ -39,6 +39,22 @@ describe('updateAgentPolicySpaces', () => { jest .mocked(appContextService.getInternalUserSOClientWithoutSpaceExtension()) .updateObjectsSpaces.mockResolvedValue({ objects: [] }); + + jest + .mocked(appContextService.getInternalUserSOClientWithoutSpaceExtension()) + .find.mockResolvedValue({ + total: 1, + page: 1, + per_page: 100, + saved_objects: [ + { + id: 'token1', + attributes: { + namespaces: ['default'], + }, + } as any, + ], + }); }); it('does nothings if agent policy already in correct space', async () => { @@ -87,6 +103,18 @@ describe('updateAgentPolicySpaces', () => { ['default'], { namespace: 'default', refresh: 'wait_for' } ); + + expect( + jest.mocked(appContextService.getInternalUserSOClientWithoutSpaceExtension()).bulkUpdate + ).toBeCalledWith([ + { + id: 'token1', + type: 'fleet-uninstall-tokens', + attributes: { + namespaces: ['test'], + }, + }, + ]); }); it('throw when trying to change space to a policy with reusable package policies', async () => { diff --git a/x-pack/plugins/fleet/server/services/spaces/agent_policy.ts b/x-pack/plugins/fleet/server/services/spaces/agent_policy.ts index 2f8d5ff1b14c7..e123ca4426654 100644 --- a/x-pack/plugins/fleet/server/services/spaces/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/spaces/agent_policy.ts @@ -13,6 +13,8 @@ import { AGENTS_INDEX, AGENT_POLICY_SAVED_OBJECT_TYPE, PACKAGE_POLICY_SAVED_OBJECT_TYPE, + SO_SEARCH_LIMIT, + UNINSTALL_TOKENS_SAVED_OBJECT_TYPE, } from '../../../common/constants'; import { appContextService } from '../app_context'; @@ -22,6 +24,7 @@ import { packagePolicyService } from '../package_policy'; import { FleetError, HostedAgentPolicyRestrictionRelatedError } from '../../errors'; import { isSpaceAwarenessEnabled } from './helpers'; +import type { UninstallTokenSOAttributes } from '../security/uninstall_token_service'; export async function updateAgentPolicySpaces({ agentPolicyId, @@ -112,6 +115,25 @@ export async function updateAgentPolicySpaces({ } } + // Update uninstall tokens + const uninstallTokensRes = await soClient.find({ + perPage: SO_SEARCH_LIMIT, + type: UNINSTALL_TOKENS_SAVED_OBJECT_TYPE, + filter: `${UNINSTALL_TOKENS_SAVED_OBJECT_TYPE}.attributes.policy_id:"${agentPolicyId}"`, + }); + + if (uninstallTokensRes.total > 0) { + await soClient.bulkUpdate( + uninstallTokensRes.saved_objects.map((so) => ({ + id: so.id, + type: UNINSTALL_TOKENS_SAVED_OBJECT_TYPE, + attributes: { + namespaces: newSpaceIds, + }, + })) + ); + } + // Update fleet server index agents, enrollment api keys await esClient.updateByQuery({ index: ENROLLMENT_API_KEYS_INDEX, diff --git a/x-pack/test/fleet_api_integration/apis/space_awareness/change_space_agent_policies.ts b/x-pack/test/fleet_api_integration/apis/space_awareness/change_space_agent_policies.ts index 4d1d08ac7b35c..df3aa6f8f257b 100644 --- a/x-pack/test/fleet_api_integration/apis/space_awareness/change_space_agent_policies.ts +++ b/x-pack/test/fleet_api_integration/apis/space_awareness/change_space_agent_policies.ts @@ -109,18 +109,29 @@ export default function (providerContext: FtrProviderContext) { }) .catch(() => {}); }); - async function assertPolicyAvailableInSpace(spaceId?: string) { - await apiClient.getAgentPolicy(defaultSpacePolicy1.item.id, spaceId); + + async function assertPackagePolicyAvailableInSpace(spaceId?: string) { await apiClient.getPackagePolicy(defaultPackagePolicy1.item.id, spaceId); + } + + async function assertPackagePolicyNotAvailableInSpace(spaceId?: string) { + await expectToRejectWithNotFound(() => + apiClient.getPackagePolicy(defaultPackagePolicy1.item.id, spaceId) + ); + } + + async function assertAgentPolicyAvailableInSpace(policyId: string, spaceId?: string) { + await apiClient.getAgentPolicy(policyId, spaceId); const enrollmentApiKeys = await apiClient.getEnrollmentApiKeys(spaceId); - expect( - enrollmentApiKeys.items.find((item) => item.policy_id === defaultSpacePolicy1.item.id) - ).not.to.be(undefined); + expect(enrollmentApiKeys.items.find((item) => item.policy_id === policyId)).not.to.be( + undefined + ); const agents = await apiClient.getAgents(spaceId); - expect( - agents.items.filter((a) => a.policy_id === defaultSpacePolicy1.item.id).length - ).to.be(1); + expect(agents.items.filter((a) => a.policy_id === policyId).length).to.be(1); + + const uninstallTokens = await apiClient.getUninstallTokens(spaceId); + expect(uninstallTokens.items.filter((t) => t.policy_id === policyId).length).to.be(1); } async function assertEnrollemntApiKeysForSpace(spaceId?: string, policyIds?: string[]) { @@ -136,23 +147,19 @@ export default function (providerContext: FtrProviderContext) { expect([...foundPolicyIds].sort()).to.eql(policyIds?.sort()); } - async function assertPolicyNotAvailableInSpace(spaceId?: string) { - await expectToRejectWithNotFound(() => - apiClient.getPackagePolicy(defaultPackagePolicy1.item.id, spaceId) - ); - await expectToRejectWithNotFound(() => - apiClient.getAgentPolicy(defaultSpacePolicy1.item.id, spaceId) - ); + async function assertAgentPolicyNotAvailableInSpace(policyId: string, spaceId?: string) { + await expectToRejectWithNotFound(() => apiClient.getAgentPolicy(policyId, spaceId)); const enrollmentApiKeys = await apiClient.getEnrollmentApiKeys(spaceId); - expect( - enrollmentApiKeys.items.find((item) => item.policy_id === defaultSpacePolicy1.item.id) - ).to.be(undefined); + expect(enrollmentApiKeys.items.find((item) => item.policy_id === policyId)).to.be( + undefined + ); const agents = await apiClient.getAgents(spaceId); - expect( - agents.items.filter((a) => a.policy_id === defaultSpacePolicy1.item.id).length - ).to.be(0); + expect(agents.items.filter((a) => a.policy_id === policyId).length).to.be(0); + + const uninstallTokens = await apiClient.getUninstallTokens(spaceId); + expect(uninstallTokens.items.filter((t) => t.policy_id === policyId).length).to.be(0); } async function assertAgentSpaces(agentId: string, expectedSpaces: string[]) { @@ -173,8 +180,11 @@ export default function (providerContext: FtrProviderContext) { space_ids: ['default', TEST_SPACE_1], }); - await assertPolicyAvailableInSpace(); - await assertPolicyAvailableInSpace(TEST_SPACE_1); + await assertAgentPolicyAvailableInSpace(defaultSpacePolicy1.item.id); + await assertAgentPolicyAvailableInSpace(defaultSpacePolicy1.item.id, TEST_SPACE_1); + + await assertPackagePolicyAvailableInSpace(); + await assertPackagePolicyAvailableInSpace(TEST_SPACE_1); await assertAgentSpaces(policy1AgentId, ['default', TEST_SPACE_1]); await assertAgentSpaces(policy2AgentId, ['default']); @@ -184,6 +194,9 @@ export default function (providerContext: FtrProviderContext) { defaultSpacePolicy2.item.id, ]); await assertEnrollemntApiKeysForSpace(TEST_SPACE_1, [defaultSpacePolicy1.item.id]); + // Ensure no side effect on other policies + await assertAgentPolicyAvailableInSpace(defaultSpacePolicy2.item.id); + await assertAgentPolicyNotAvailableInSpace(defaultSpacePolicy2.item.id, TEST_SPACE_1); }); it('should allow set policy in test space only', async () => { @@ -194,12 +207,17 @@ export default function (providerContext: FtrProviderContext) { space_ids: [TEST_SPACE_1], }); - await assertPolicyNotAvailableInSpace(); - await assertPolicyAvailableInSpace(TEST_SPACE_1); + await assertAgentPolicyNotAvailableInSpace(defaultSpacePolicy1.item.id); + await assertAgentPolicyAvailableInSpace(defaultSpacePolicy1.item.id, TEST_SPACE_1); + await assertPackagePolicyAvailableInSpace(TEST_SPACE_1); + await assertPackagePolicyNotAvailableInSpace(); await assertAgentSpaces(policy1AgentId, [TEST_SPACE_1]); await assertAgentSpaces(policy2AgentId, ['default']); await assertEnrollemntApiKeysForSpace('default', [defaultSpacePolicy2.item.id]); await assertEnrollemntApiKeysForSpace(TEST_SPACE_1, [defaultSpacePolicy1.item.id]); + // Ensure no side effect on other policies + await assertAgentPolicyAvailableInSpace(defaultSpacePolicy2.item.id); + await assertAgentPolicyNotAvailableInSpace(defaultSpacePolicy2.item.id, TEST_SPACE_1); }); it('should not allow add policy to a space where user do not have access', async () => { From 4a2de76333063a1c6e68eeeaf4697753593928a5 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 13 Nov 2024 01:17:12 +1100 Subject: [PATCH 026/105] Unauthorized route migration for routes owned by obs-ux-logs-team (#198349) ### Authz API migration for unauthorized routes This PR migrates unauthorized routes owned by your team to a new security configuration. Please refer to the documentation for more information: [Authorization API](https://docs.elastic.dev/kibana-dev-docs/key-concepts/security-api-authorization) ### **Before migration:** ```ts router.get({ path: '/api/path', ... }, handler); ``` ### **After migration:** ```ts router.get({ path: '/api/path', security: { authz: { enabled: false, reason: 'This route is opted out from authorization because ...', }, }, ... }, handler); ``` ### What to do next? 1. Review the changes in this PR. 2. Elaborate on the reasoning to opt-out of authorization. 3. Routes without a compelling reason to opt-out of authorization should plan to introduce them as soon as possible. 2. You might need to update your tests to reflect the new security configuration: - If you have snapshot tests that include the route definition. ## Any questions? If you have any questions or need help with API authorization, please reach out to the `@elastic/kibana-security` team. Co-authored-by: Elastic Machine Co-authored-by: Marco Antonio Ghiani --- .../server/routes/fields_metadata/find_fields_metadata.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x-pack/plugins/fields_metadata/server/routes/fields_metadata/find_fields_metadata.ts b/x-pack/plugins/fields_metadata/server/routes/fields_metadata/find_fields_metadata.ts index 5e518618d98d8..422c16a726843 100644 --- a/x-pack/plugins/fields_metadata/server/routes/fields_metadata/find_fields_metadata.ts +++ b/x-pack/plugins/fields_metadata/server/routes/fields_metadata/find_fields_metadata.ts @@ -24,6 +24,12 @@ export const initFindFieldsMetadataRoute = ({ .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: 'This route is opted out from authorization', + }, + }, validate: { request: { query: createValidationFunction(fieldsMetadataV1.findFieldsMetadataRequestQueryRT), From 06986e4a86a0fa3c3951fcb6b2ba34ebe2769820 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Tue, 12 Nov 2024 15:46:39 +0100 Subject: [PATCH 027/105] [Security Solution] Add Alert Suppression editable component (#198673) **Partially addresses:** https://github.com/elastic/kibana/issues/171520 ## Summary This PR adds is built on top of https://github.com/elastic/kibana/pull/193828 and https://github.com/elastic/kibana/pull/196948 and adds an Alert Suppression editable component for Three Way Diff tab's final edit side of the upgrade prebuilt rule workflow. ## Details https://github.com/elastic/kibana/issues/171520 required adding editable components for each field diffable rule field. Alert Suppression edit component was extracted from Define Rule Step Component into a separate reusable component. To simplify the logic it was split into common Alert Suppression and Threshold Alert Suppression since the latter is a specific use case. ## Caveats Upgrade prebuilt rules workflow is quite different from rule creation and editing. In create and edit rule forms users are capable to change any field at their will. Upgrade prebuilt rules workflow allow to modify only specific fields having diff in the current rule upgrade. There are fields which depend on each other. In particular Alert Suppression isn't supported for EQL sequence though it's addressed in https://github.com/elastic/kibana/pull/189725. - Alert Suppression editable component in Three Way Diff workflow isn't disabled EQL sequence rule queries. Alert suppression support for rules with EQL sequence queries is implemented in https://github.com/elastic/kibana/pull/189725. - Machine learning rule type require running selected machine learning jobs otherwise input could be disabled in case of there are no fields to pick from otherwise a warning message below the combobox is shown. ## How to test The simplest way to test is via patching installed prebuilt rules via Rule Patch API. Please follow steps below - Enable Prebuilt rule customization feature by adding a `prebuiltRulesCustomizationEnabled` feature flag - Run Kibana locally - Install a prebuilt rule, e.g. `Potential Code Execution via Postgresql` with rule_id `2a692072-d78d-42f3-a48a-775677d79c4e` - Patch the installed rule by running a query below ```bash curl -X PATCH --user elastic:changeme -H 'Content-Type: application/json' -H 'kbn-xsrf: 123' -H "elastic-api-version: 2023-10-31" -d '{"rule_id":"2a692072-d78d-42f3-a48a-775677d79c4e","version":1,"alert_suppression":{"group_by":["host.name"]}}' http://localhost:5601/kbn/api/detection_engine/rules ``` - Open `Detection Rules (SIEM)` Page -> `Rule Updates` -> click on `Potential Code Execution via Postgresql` rule -> expand `EQL Query` to see EQL Query -> press `Edit` button ## Screenshots Custom query prebuilt rule (UI looks similar for EQL, Indicator Match, New Terms and ES|QL rule types) ![image](https://github.com/user-attachments/assets/86015d5b-e252-4d0b-9aa3-fc14679a493b) Machine learning prebuilt rule with a diff in alert suppression ![image](https://github.com/user-attachments/assets/210246cd-27fd-4976-befc-dee023101ec9) Threshold prebuilt rule ![image](https://github.com/user-attachments/assets/44b0c1bc-4134-4d58-bd9a-e8e2d4c50802) --- oas_docs/output/kibana.serverless.yaml | 13 +- oas_docs/output/kibana.yaml | 13 +- .../rule_schema/common_attributes.gen.ts | 7 +- .../rule_schema/common_attributes.schema.yaml | 13 +- ...ections_api_2023_10_31.bundled.schema.yaml | 12 +- ...ections_api_2023_10_31.bundled.schema.yaml | 12 +- .../markdown_editor/plugins/index.ts | 4 +- .../plugins/insight/index.test.tsx | 2 +- .../markdown_editor/plugins/insight/index.tsx | 6 +- .../plugins/osquery/plugin.tsx | 2 +- .../plugins/timeline/plugin.tsx | 2 +- .../common/hooks/use_upselling.test.tsx | 4 +- .../public/common/hooks/use_upselling.ts | 4 +- .../public/common/test/eui/combobox.ts | 79 +++++ .../components/alert_suppression_edit.tsx | 64 ++++ .../missing_fields_strategy_selector.tsx | 61 ++++ .../suppression_duration_selector.tsx | 140 +++++++++ .../suppression_fields_selector.tsx | 46 +++ .../components/suppression_info_icon.tsx} | 21 +- .../components/translations.ts | 94 ++++++ .../constants/default_duration.ts | 17 ++ .../constants/fields.ts | 13 + .../alert_suppression_edit/index.ts | 11 + .../alert_suppression_edit/test_helpers.ts | 72 +++++ .../components/duration_input/index.tsx | 82 ++--- .../components/duration_input/translations.ts | 7 + .../related_integrations.test.tsx | 88 +----- .../related_integrations/test_helpers.ts | 47 +++ .../fields.ts | 8 + .../threshold_alert_suppression_edit/index.ts | 9 + .../threshold_alert_suppression_edit.tsx | 63 ++++ .../translations.tsx | 32 ++ ...a_views.ts => use_data_view_list_items.ts} | 2 +- .../data_view_selector_field.test.tsx | 14 +- .../data_view_selector_field.tsx | 4 +- ...a_views.ts => use_data_view_list_items.ts} | 2 +- .../components/description_step/helpers.tsx | 8 +- .../description_step/index.test.tsx | 63 ++-- .../components/description_step/index.tsx | 23 +- .../description_step/translations.ts | 4 +- .../components/multi_select_fields/index.tsx | 18 +- .../components/step_about_rule/index.test.tsx | 25 +- .../step_define_rule/index.test.tsx | 208 +++++-------- .../components/step_define_rule/index.tsx | 283 +++--------------- .../components/step_define_rule/schema.tsx | 67 ++--- .../step_define_rule/translations.tsx | 15 +- .../use_persistent_alert_suppression_state.ts | 77 +++++ .../components/step_define_rule/utils.ts | 11 +- .../rule_creation_ui/pages/form.test.ts | 3 +- .../pages/rule_creation/helpers.test.ts | 29 +- .../pages/rule_creation/helpers.ts | 25 +- .../pages/rule_creation/index.tsx | 14 +- .../pages/rule_editing/index.tsx | 4 +- ...rt_suppression_fields_validator_factory.ts | 25 ++ .../custom_query_rule_field_edit.tsx | 3 + .../final_edit/eql_rule_field_edit.tsx | 3 + .../final_edit/esql_rule_field_edit.tsx | 23 ++ .../fields/alert_suppression/form_schema.ts | 37 +++ .../fields/alert_suppression/index.ts | 8 + .../suppression_edit_adapter.tsx | 81 +++++ .../suppression_edit_form.tsx | 70 +++++ .../fields/alert_suppression/translations.tsx | 38 +++ .../data_source/data_source_edit_form.tsx | 16 +- .../data_source_type_selector_field.tsx | 13 +- .../fields/data_source/index_pattern_edit.tsx | 2 +- .../fields/data_source/translations.tsx | 18 +- .../final_edit/fields/hooks/use_data_view.ts | 59 ++++ .../hooks/use_diffable_rule_data_view.ts | 33 ++ .../fields/kql_query/kql_query_edit.tsx | 54 +--- .../form_schema.ts | 33 ++ .../threshold_alert_suppression/index.ts | 8 + .../suppression_edit_form.tsx | 70 +++++ .../three_way_diff/final_edit/final_edit.tsx | 10 +- .../machine_learning_rule_field_edit.tsx | 23 ++ .../final_edit/new_terms_rule_field_edit.tsx | 3 + .../saved_query_rule_field_edit.tsx | 3 + .../threat_match_rule_field_edit.tsx | 3 + .../final_edit/threshold_rule_field_edit.tsx | 3 + .../components/rules_table/__mocks__/mock.ts | 30 +- .../detection_engine/rules/helpers.test.tsx | 29 +- .../pages/detection_engine/rules/helpers.tsx | 24 +- .../pages/detection_engine/rules/types.ts | 19 +- .../pages/detection_engine/rules/utils.ts | 23 +- .../plugins/security_solution/tsconfig.json | 1 + .../translations/translations/fr-FR.json | 8 - .../translations/translations/ja-JP.json | 8 - .../translations/translations/zh-CN.json | 8 - .../common_flows_supression_ess_basic.cy.ts | 7 +- .../machine_learning_rule_suppression.cy.ts | 4 +- .../rule_edit/esql_rule.cy.ts | 8 +- .../rule_edit/indicator_match_rule.cy.ts | 9 +- .../rule_edit/machine_learning_rule.cy.ts | 15 +- .../rule_edit/new_terms_rule.cy.ts | 9 +- .../rule_edit/threshold_rule.cy.ts | 11 +- .../cypress/screens/create_new_rule.ts | 13 +- .../cypress/tasks/create_new_rule.ts | 7 +- 96 files changed, 1942 insertions(+), 877 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/test/eui/combobox.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/alert_suppression_edit.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/missing_fields_strategy_selector.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_duration_selector.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_fields_selector.tsx rename x-pack/plugins/security_solution/public/detection_engine/{rule_creation_ui/components/suppression_info_icon/index.tsx => rule_creation/components/alert_suppression_edit/components/suppression_info_icon.tsx} (80%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/translations.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/constants/default_duration.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/constants/fields.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/index.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/test_helpers.ts rename x-pack/plugins/security_solution/public/detection_engine/{rule_creation_ui => rule_creation}/components/duration_input/index.tsx (68%) rename x-pack/plugins/security_solution/public/detection_engine/{rule_creation_ui => rule_creation}/components/duration_input/translations.ts (82%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/related_integrations/test_helpers.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/fields.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/index.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/threshold_alert_suppression_edit.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/translations.tsx rename x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/__mocks__/{use_data_views.ts => use_data_view_list_items.ts} (81%) rename x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/{use_data_views.ts => use_data_view_list_items.ts} (95%) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/use_persistent_alert_suppression_state.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/validators/alert_suppression_fields_validator_factory.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/esql_rule_field_edit.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/form_schema.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/index.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_adapter.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/suppression_edit_form.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/alert_suppression/translations.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/hooks/use_data_view.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/hooks/use_diffable_rule_data_view.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threshold_alert_suppression/form_schema.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threshold_alert_suppression/index.ts create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/fields/threshold_alert_suppression/suppression_edit_form.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_edit/machine_learning_rule_field_edit.tsx diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index 5f18154db449d..95c201de052c2 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -39976,17 +39976,20 @@ components: type: object properties: unit: - enum: - - s - - m - - h - type: string + $ref: >- + #/components/schemas/Security_Detections_API_AlertSuppressionDurationUnit value: minimum: 1 type: integer required: - value - unit + Security_Detections_API_AlertSuppressionDurationUnit: + enum: + - s + - m + - h + type: string Security_Detections_API_AlertSuppressionGroupBy: items: type: string diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index 133dede5fcd0c..8b4953b4149a2 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -48220,17 +48220,20 @@ components: type: object properties: unit: - enum: - - s - - m - - h - type: string + $ref: >- + #/components/schemas/Security_Detections_API_AlertSuppressionDurationUnit value: minimum: 1 type: integer required: - value - unit + Security_Detections_API_AlertSuppressionDurationUnit: + enum: + - s + - m + - h + type: string Security_Detections_API_AlertSuppressionGroupBy: items: type: string diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.gen.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.gen.ts index 1bf3bfb5e2445..2d722e7d5076a 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.gen.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.gen.ts @@ -555,10 +555,15 @@ export const RuleExceptionList = z.object({ namespace_type: z.enum(['agnostic', 'single']), }); +export type AlertSuppressionDurationUnit = z.infer; +export const AlertSuppressionDurationUnit = z.enum(['s', 'm', 'h']); +export type AlertSuppressionDurationUnitEnum = typeof AlertSuppressionDurationUnit.enum; +export const AlertSuppressionDurationUnitEnum = AlertSuppressionDurationUnit.enum; + export type AlertSuppressionDuration = z.infer; export const AlertSuppressionDuration = z.object({ value: z.number().int().min(1), - unit: z.enum(['s', 'm', 'h']), + unit: AlertSuppressionDurationUnit, }); /** diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.schema.yaml b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.schema.yaml index 088153cca4885..029a71b9e0a1c 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.schema.yaml +++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema/common_attributes.schema.yaml @@ -581,6 +581,13 @@ components: - type - namespace_type + AlertSuppressionDurationUnit: + type: string + enum: + - s + - m + - h + AlertSuppressionDuration: type: object properties: @@ -588,11 +595,7 @@ components: type: integer minimum: 1 unit: - type: string - enum: - - s - - m - - h + $ref: '#/components/schemas/AlertSuppressionDurationUnit' required: - value - unit diff --git a/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_detections_api_2023_10_31.bundled.schema.yaml b/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_detections_api_2023_10_31.bundled.schema.yaml index ebd4c93280090..7e8d7a61bff2c 100644 --- a/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_detections_api_2023_10_31.bundled.schema.yaml +++ b/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_detections_api_2023_10_31.bundled.schema.yaml @@ -1560,17 +1560,19 @@ components: type: object properties: unit: - enum: - - s - - m - - h - type: string + $ref: '#/components/schemas/AlertSuppressionDurationUnit' value: minimum: 1 type: integer required: - value - unit + AlertSuppressionDurationUnit: + enum: + - s + - m + - h + type: string AlertSuppressionGroupBy: items: type: string diff --git a/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_detections_api_2023_10_31.bundled.schema.yaml b/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_detections_api_2023_10_31.bundled.schema.yaml index 30a7ae3ea343e..58456e71140a0 100644 --- a/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_detections_api_2023_10_31.bundled.schema.yaml +++ b/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_detections_api_2023_10_31.bundled.schema.yaml @@ -850,17 +850,19 @@ components: type: object properties: unit: - enum: - - s - - m - - h - type: string + $ref: '#/components/schemas/AlertSuppressionDurationUnit' value: minimum: 1 type: integer required: - value - unit + AlertSuppressionDurationUnit: + enum: + - s + - m + - h + type: string AlertSuppressionGroupBy: items: type: string diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/index.ts b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/index.ts index 607ed6d94959b..b6067ac21eb1d 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/index.ts @@ -24,8 +24,8 @@ export const uiPlugins = ({ insightsUpsellingMessage, interactionsUpsellingMessage, }: { - insightsUpsellingMessage: string | null; - interactionsUpsellingMessage: string | null; + insightsUpsellingMessage?: string; + interactionsUpsellingMessage?: string; }) => { const currentPlugins = nonStatefulUiPlugins.map((plugin) => plugin.name); const insightPluginWithLicense = insightMarkdownPlugin.plugin({ diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.test.tsx index 37d4e004edf54..026e070f320df 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.test.tsx @@ -135,7 +135,7 @@ describe('plugin', () => { }); it('show investigate message when insightsUpsellingMessage is not provided', () => { - const result = plugin({ insightsUpsellingMessage: null }); + const result = plugin({ insightsUpsellingMessage: undefined }); expect(result.button.label).toEqual('Investigate'); }); diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.tsx index e8fa43d0a189e..794b17a219208 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/insight/index.tsx @@ -541,11 +541,7 @@ const exampleInsight = `${insightPrefix}{ ] }}`; -export const plugin = ({ - insightsUpsellingMessage, -}: { - insightsUpsellingMessage: string | null; -}) => { +export const plugin = ({ insightsUpsellingMessage }: { insightsUpsellingMessage?: string }) => { return { name: 'insights', button: { diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/osquery/plugin.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/osquery/plugin.tsx index 6a37280f9ef23..67b3f9e2b4f8a 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/osquery/plugin.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/osquery/plugin.tsx @@ -161,7 +161,7 @@ const OsqueryEditor = React.memo(OsqueryEditorComponent); export const plugin = ({ interactionsUpsellingMessage, }: { - interactionsUpsellingMessage: string | null; + interactionsUpsellingMessage?: string; }) => { return { name: 'osquery', diff --git a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/timeline/plugin.tsx b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/timeline/plugin.tsx index 40b2fba4b84d0..4d5b2e14e0d95 100644 --- a/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/timeline/plugin.tsx +++ b/x-pack/plugins/security_solution/public/common/components/markdown_editor/plugins/timeline/plugin.tsx @@ -78,7 +78,7 @@ const TimelineEditor = memo(TimelineEditorComponent); export const plugin = ({ interactionsUpsellingMessage, }: { - interactionsUpsellingMessage: string | null; + interactionsUpsellingMessage?: string; }): EuiMarkdownEditorUiPlugin => { return { name: ID, diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx index ee783bcd19e3d..c18a6282eb373 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upselling.test.tsx @@ -71,7 +71,7 @@ describe('use_upselling', () => { expect(result.all.length).toBe(1); // assert that it should not cause unnecessary re-renders }); - test('useUpsellingMessage returns null when upsellingMessageId not found', () => { + test('useUpsellingMessage returns undefined when upsellingMessageId not found', () => { const emptyMessages = {}; mockUpselling.setPages(emptyMessages); @@ -81,6 +81,6 @@ describe('use_upselling', () => { wrapper: RenderWrapper, } ); - expect(result.current).toBe(null); + expect(result.current).toBeUndefined(); }); }); diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upselling.ts b/x-pack/plugins/security_solution/public/common/hooks/use_upselling.ts index 8ef01b5b56a25..9f452bb4f2872 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upselling.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upselling.ts @@ -22,11 +22,11 @@ export const useUpsellingComponent = (id: UpsellingSectionId): React.ComponentTy return useMemo(() => upsellingSections?.get(id) ?? null, [id, upsellingSections]); }; -export const useUpsellingMessage = (id: UpsellingMessageId): string | null => { +export const useUpsellingMessage = (id: UpsellingMessageId): string | undefined => { const upselling = useUpsellingService(); const upsellingMessages = useObservable(upselling.messages$, upselling.getMessagesValue()); - return useMemo(() => upsellingMessages?.get(id) ?? null, [id, upsellingMessages]); + return useMemo(() => upsellingMessages?.get(id), [id, upsellingMessages]); }; export const useUpsellingPage = (pageName: SecurityPageName): React.ComponentType | null => { diff --git a/x-pack/plugins/security_solution/public/common/test/eui/combobox.ts b/x-pack/plugins/security_solution/public/common/test/eui/combobox.ts new file mode 100644 index 0000000000000..dad99a3c426d4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/test/eui/combobox.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { act, fireEvent, waitFor } from '@testing-library/react'; + +export function showEuiComboBoxOptions(comboBoxToggleButton: HTMLElement): Promise { + fireEvent.click(comboBoxToggleButton); + + return waitFor(() => { + const listWithOptionsElement = document.querySelector('[role="listbox"]'); + const emptyListElement = document.querySelector('.euiComboBoxOptionsList__empty'); + + expect(listWithOptionsElement || emptyListElement).toBeInTheDocument(); + }); +} + +type SelectEuiComboBoxOptionParameters = + | { + comboBoxToggleButton: HTMLElement; + optionIndex: number; + optionText?: undefined; + } + | { + comboBoxToggleButton: HTMLElement; + optionText: string; + optionIndex?: undefined; + }; + +export function selectEuiComboBoxOption({ + comboBoxToggleButton, + optionIndex, + optionText, +}: SelectEuiComboBoxOptionParameters): Promise { + return act(async () => { + await showEuiComboBoxOptions(comboBoxToggleButton); + + const options = Array.from( + document.querySelectorAll('[data-test-subj*="comboBoxOptionsList"] [role="option"]') + ); + + if (typeof optionText === 'string') { + const optionToSelect = options.find((option) => option.textContent === optionText); + + if (optionToSelect) { + fireEvent.click(optionToSelect); + } else { + throw new Error( + `Could not find option with text "${optionText}". Available options: ${options + .map((option) => option.textContent) + .join(', ')}` + ); + } + } else { + fireEvent.click(options[optionIndex]); + } + }); +} + +export function selectFirstEuiComboBoxOption({ + comboBoxToggleButton, +}: { + comboBoxToggleButton: HTMLElement; +}): Promise { + return selectEuiComboBoxOption({ comboBoxToggleButton, optionIndex: 0 }); +} + +export function clearEuiComboBoxSelection({ + clearButton, +}: { + clearButton: HTMLElement; +}): Promise { + return act(async () => { + fireEvent.click(clearButton); + }); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/alert_suppression_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/alert_suppression_edit.tsx new file mode 100644 index 0000000000000..5c6099529e920 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/alert_suppression_edit.tsx @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { EuiPanel, EuiText, EuiToolTip } from '@elastic/eui'; +import type { DataViewFieldBase } from '@kbn/es-query'; +import { useFormData } from '../../../../../shared_imports'; +import { MissingFieldsStrategySelector } from './missing_fields_strategy_selector'; +import { SuppressionDurationSelector } from './suppression_duration_selector'; +import { SuppressionFieldsSelector } from './suppression_fields_selector'; +import { ALERT_SUPPRESSION_FIELDS_FIELD_NAME } from '../constants/fields'; + +interface AlertSuppressionEditProps { + suppressibleFields: DataViewFieldBase[]; + labelAppend?: React.ReactNode; + disabled?: boolean; + disabledText?: string; + warningText?: string; +} + +export const AlertSuppressionEdit = memo(function AlertSuppressionEdit({ + suppressibleFields, + labelAppend, + disabled, + disabledText, + warningText, +}: AlertSuppressionEditProps): JSX.Element { + const [{ [ALERT_SUPPRESSION_FIELDS_FIELD_NAME]: suppressionFields }] = useFormData<{ + [ALERT_SUPPRESSION_FIELDS_FIELD_NAME]: string[]; + }>({ + watch: ALERT_SUPPRESSION_FIELDS_FIELD_NAME, + }); + const hasSelectedFields = suppressionFields?.length > 0; + const content = ( + <> + + {warningText && ( + + {warningText} + + )} + + + + + + ); + + return disabled && disabledText ? ( + + {content} + + ) : ( + content + ); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/missing_fields_strategy_selector.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/missing_fields_strategy_selector.tsx new file mode 100644 index 0000000000000..a7b38843a61ce --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/missing_fields_strategy_selector.tsx @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import type { EuiFormRowProps, EuiRadioGroupOption, EuiRadioGroupProps } from '@elastic/eui'; +import { RadioGroupField } from '@kbn/es-ui-shared-plugin/static/forms/components'; +import { AlertSuppressionMissingFieldsStrategyEnum } from '../../../../../../common/api/detection_engine'; +import { UseField } from '../../../../../shared_imports'; +import { SuppressionInfoIcon } from './suppression_info_icon'; +import { ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME } from '../constants/fields'; +import * as i18n from './translations'; + +interface MissingFieldsStrategySelectorProps { + disabled?: boolean; +} + +export function MissingFieldsStrategySelector({ + disabled, +}: MissingFieldsStrategySelectorProps): JSX.Element { + const radioFieldProps: Partial = useMemo( + () => ({ + options: ALERT_SUPPRESSION_MISSING_FIELDS_STRATEGY_OPTIONS, + 'data-test-subj': 'suppressionMissingFieldsOptions', + disabled, + }), + [disabled] + ); + + return ( + + ); +} + +const EUI_FORM_ROW_PROPS: Partial = { + label: ( + + {i18n.ALERT_SUPPRESSION_MISSING_FIELDS_LABEL} + + ), + 'data-test-subj': 'alertSuppressionMissingFields', +}; + +const ALERT_SUPPRESSION_MISSING_FIELDS_STRATEGY_OPTIONS: EuiRadioGroupOption[] = [ + { + id: AlertSuppressionMissingFieldsStrategyEnum.suppress, + label: i18n.ALERT_SUPPRESSION_MISSING_FIELDS_SUPPRESS_OPTION, + }, + { + id: AlertSuppressionMissingFieldsStrategyEnum.doNotSuppress, + label: i18n.ALERT_SUPPRESSION_MISSING_FIELDS_DO_NOT_SUPPRESS_OPTION, + }, +]; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_duration_selector.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_duration_selector.tsx new file mode 100644 index 0000000000000..7cf5eeb3018b1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_duration_selector.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, { memo, useEffect } from 'react'; +import { EuiFormRow, EuiRadioGroup, EuiToolTip, useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/css'; +import type { FieldHook } from '../../../../../shared_imports'; +import { UseMultiFields } from '../../../../../shared_imports'; +import { AlertSuppressionDurationType } from '../../../../../detections/pages/detection_engine/rules/types'; +import { DurationInput } from '../../duration_input'; +import { + ALERT_SUPPRESSION_DURATION_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_UNIT_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_VALUE_FIELD_NAME, +} from '../constants/fields'; +import * as i18n from './translations'; + +interface AlertSuppressionDurationProps { + onlyPerTimePeriod?: boolean; + onlyPerTimePeriodReasonMessage?: string; + disabled?: boolean; +} + +export function SuppressionDurationSelector({ + onlyPerTimePeriod, + onlyPerTimePeriodReasonMessage, + disabled, +}: AlertSuppressionDurationProps): JSX.Element { + return ( + + + fields={{ + suppressionDurationSelector: { + path: ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME, + }, + suppressionDurationValue: { + path: `${ALERT_SUPPRESSION_DURATION_FIELD_NAME}.${ALERT_SUPPRESSION_DURATION_VALUE_FIELD_NAME}`, + }, + suppressionDurationUnit: { + path: `${ALERT_SUPPRESSION_DURATION_FIELD_NAME}.${ALERT_SUPPRESSION_DURATION_UNIT_FIELD_NAME}`, + }, + }} + > + {({ suppressionDurationSelector, suppressionDurationValue, suppressionDurationUnit }) => ( + + )} + + + ); +} + +interface SuppressionDurationSelectorFieldsProps { + suppressionDurationSelectorField: FieldHook; + suppressionDurationValueField: FieldHook; + suppressionDurationUnitField: FieldHook; + onlyPerTimePeriod?: boolean; + onlyPerTimePeriodReasonMessage?: string; + disabled?: boolean; +} + +const SuppressionDurationSelectorFields = memo(function SuppressionDurationSelectorFields({ + suppressionDurationSelectorField, + suppressionDurationValueField, + suppressionDurationUnitField, + onlyPerTimePeriod = false, + onlyPerTimePeriodReasonMessage, + disabled, +}: SuppressionDurationSelectorFieldsProps): JSX.Element { + const { euiTheme } = useEuiTheme(); + const { value: durationType, setValue: setDurationType } = suppressionDurationSelectorField; + + useEffect(() => { + if (onlyPerTimePeriod && durationType !== AlertSuppressionDurationType.PerTimePeriod) { + setDurationType(AlertSuppressionDurationType.PerTimePeriod); + } + }, [onlyPerTimePeriod, durationType, setDurationType]); + + return ( + <> + + <> {i18n.ALERT_SUPPRESSION_DURATION_PER_RULE_EXECUTION_OPTION} +
    + ) : ( + i18n.ALERT_SUPPRESSION_DURATION_PER_RULE_EXECUTION_OPTION + ), + disabled: onlyPerTimePeriod ? true : disabled, + }, + { + id: AlertSuppressionDurationType.PerTimePeriod, + disabled, + label: i18n.ALERT_SUPPRESSION_DURATION_PER_TIME_PERIOD_OPTION, + }, + ]} + onChange={(id) => { + suppressionDurationSelectorField.setValue(id); + }} + data-test-subj="alertSuppressionDurationOptions" + /> +
    + +
    + + ); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_fields_selector.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_fields_selector.tsx new file mode 100644 index 0000000000000..72eea027288f0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_fields_selector.tsx @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiFormRow } from '@elastic/eui'; +import type { DataViewFieldBase } from '@kbn/es-query'; +import { UseField } from '../../../../../shared_imports'; +import { MultiSelectFieldsAutocomplete } from '../../../../rule_creation_ui/components/multi_select_fields'; +import { ALERT_SUPPRESSION_FIELDS_FIELD_NAME } from '../constants/fields'; +import * as i18n from './translations'; + +interface SuppressionFieldsSelectorProps { + suppressibleFields: DataViewFieldBase[]; + labelAppend?: React.ReactNode; + disabled?: boolean; +} + +export function SuppressionFieldsSelector({ + suppressibleFields, + labelAppend, + disabled, +}: SuppressionFieldsSelectorProps): JSX.Element { + return ( + + <> + + + + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/suppression_info_icon/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_info_icon.tsx similarity index 80% rename from x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/suppression_info_icon/index.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_info_icon.tsx index bb3b0db1ccdab..466600dd394da 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/suppression_info_icon/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/suppression_info_icon.tsx @@ -5,28 +5,25 @@ * 2.0. */ -import React, { useState } from 'react'; +import React from 'react'; import { EuiLink, EuiPopover, EuiText, EuiButtonIcon } from '@elastic/eui'; +import { useBoolean } from '@kbn/react-hooks'; import { FormattedMessage } from '@kbn/i18n-react'; - -import { useKibana } from '../../../../common/lib/kibana'; +import { useKibana } from '../../../../../common/lib/kibana'; const POPOVER_WIDTH = 320; /** * Icon and popover that gives hint to users how suppression for missing fields work */ -const SuppressionInfoIconComponent = () => { - const [isPopoverOpen, setIsPopoverOpen] = useState(false); +export function SuppressionInfoIcon(): JSX.Element { + const [isPopoverOpen, { off: closePopover, toggle: togglePopover }] = useBoolean(false); const { docLinks } = useKibana().services; - const onButtonClick = () => setIsPopoverOpen(!isPopoverOpen); - const closePopover = () => setIsPopoverOpen(false); - const button = ( ); @@ -59,8 +56,4 @@ const SuppressionInfoIconComponent = () => { ); -}; - -export const SuppressionInfoIcon = React.memo(SuppressionInfoIconComponent); - -SuppressionInfoIcon.displayName = 'SuppressionInfoIcon'; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/translations.ts new file mode 100644 index 0000000000000..8da7d435adfeb --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/components/translations.ts @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const ALERT_SUPPRESSION_SUPPRESS_BY_FIELD_LABEL = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.fieldsSelector.label', + { + defaultMessage: 'Suppress alerts by', + } +); + +export const ALERT_SUPPRESSION_SUPPRESS_BY_FIELD_HELP_TEXT = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.suppressByFields.helpText', + { + defaultMessage: 'Select field(s) to use for suppressing extra alerts', + } +); + +export const ALERT_SUPPRESSION_DURATION_PER_RULE_EXECUTION_OPTION = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.suppressionDuration.perRuleExecutionOption', + { + defaultMessage: 'Per rule execution', + } +); + +export const ALERT_SUPPRESSION_DURATION_PER_TIME_PERIOD_OPTION = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.suppressionDuration.perTimePeriodOption', + { + defaultMessage: 'Per time period', + } +); + +export const ALERT_SUPPRESSION_MISSING_FIELDS_LABEL = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.missingFields.label', + { + defaultMessage: 'If a suppression field is missing', + } +); + +export const ALERT_SUPPRESSION_MISSING_FIELDS_SUPPRESS_OPTION = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.missingFields.suppressOption', + { + defaultMessage: 'Suppress and group alerts for events with missing fields', + } +); + +export const ALERT_SUPPRESSION_MISSING_FIELDS_DO_NOT_SUPPRESS_OPTION = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.missingFields.doNotSuppressOption', + { + defaultMessage: 'Do not suppress alerts for events with missing fields', + } +); + +export const ALERT_SUPPRESSION_NOT_SUPPORTED_FOR_EQL_SEQUENCE = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.notSupportedForEqlSequence', + { + defaultMessage: 'Suppression is not supported for EQL sequence queries', + } +); + +export const MACHINE_LEARNING_SUPPRESSION_FIELDS_LOADING = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.machineLearningSuppressionFieldsLoading', + { + defaultMessage: 'Machine Learning suppression fields are loading', + } +); + +export const MACHINE_LEARNING_NO_SUPPRESSION_FIELDS = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.machineLearningNoSuppressionFields', + { + defaultMessage: + 'Unable to load machine Learning suppression fields, start relevant Machine Learning jobs.', + } +); + +export const ESQL_SUPPRESSION_FIELDS_LOADING = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.esqlFieldsLoading', + { + defaultMessage: 'ES|QL suppression fields are loading', + } +); + +export const MACHINE_LEARNING_SUPPRESSION_INCOMPLETE_LABEL = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.alertSuppression.machineLearningSuppressionIncomplete', + { + defaultMessage: + 'This list of fields might be incomplete as some Machine Learning jobs are not running. Start all relevant jobs for a complete list.', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/constants/default_duration.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/constants/default_duration.ts new file mode 100644 index 0000000000000..6e06d0d67031a --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/constants/default_duration.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { AlertSuppressionDurationUnitEnum } from '../../../../../../common/api/detection_engine'; +import { + ALERT_SUPPRESSION_DURATION_VALUE_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_UNIT_FIELD_NAME, +} from './fields'; + +export const ALERT_SUPPRESSION_DEFAULT_DURATION = { + [ALERT_SUPPRESSION_DURATION_VALUE_FIELD_NAME]: 5, + [ALERT_SUPPRESSION_DURATION_UNIT_FIELD_NAME]: AlertSuppressionDurationUnitEnum.m, +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/constants/fields.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/constants/fields.ts new file mode 100644 index 0000000000000..42a0583e90512 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/constants/fields.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 ALERT_SUPPRESSION_FIELDS_FIELD_NAME = 'alertSuppressionFields' as const; +export const ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME = 'alertSuppressionDurationType' as const; +export const ALERT_SUPPRESSION_DURATION_FIELD_NAME = 'alertSuppressionDuration' as const; +export const ALERT_SUPPRESSION_DURATION_VALUE_FIELD_NAME = 'value' as const; +export const ALERT_SUPPRESSION_DURATION_UNIT_FIELD_NAME = 'unit' as const; +export const ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME = 'alertSuppressionMissingFields' as const; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/index.ts new file mode 100644 index 0000000000000..a97e74726e3c4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright 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 './components/alert_suppression_edit'; +export * from './components/suppression_duration_selector'; +export * from './constants/fields'; +export * from './constants/default_duration'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/test_helpers.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/test_helpers.ts new file mode 100644 index 0000000000000..b7d6c4003e934 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/alert_suppression_edit/test_helpers.ts @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// eslint-disable-next-line import/no-extraneous-dependencies +import { act, fireEvent, waitFor, within, screen } from '@testing-library/react'; +import type { AlertSuppressionDurationUnit } from '../../../../../common/api/detection_engine'; +import { selectEuiComboBoxOption } from '../../../../common/test/eui/combobox'; + +const COMBO_BOX_TOGGLE_BUTTON_TEST_ID = 'comboBoxToggleListButton'; + +export async function setSuppressionFields(fieldNames: string[]): Promise { + const getAlertSuppressionFieldsComboBoxToggleButton = () => + within(screen.getByTestId('alertSuppressionInput')).getByTestId( + COMBO_BOX_TOGGLE_BUTTON_TEST_ID + ); + + await waitFor(() => { + expect(getAlertSuppressionFieldsComboBoxToggleButton()).toBeInTheDocument(); + }); + + for (const fieldName of fieldNames) { + await selectEuiComboBoxOption({ + comboBoxToggleButton: getAlertSuppressionFieldsComboBoxToggleButton(), + optionText: fieldName, + }); + } +} + +export function expectSuppressionFields(fieldNames: string[]): void { + for (const fieldName of fieldNames) { + expect( + within(screen.getByTestId('alertSuppressionInput')).getByTitle(fieldName) + ).toBeInTheDocument(); + } +} + +export function setDurationType(value: 'Per rule execution' | 'Per time period'): void { + act(() => { + fireEvent.click(within(screen.getByTestId('alertSuppressionDuration')).getByLabelText(value)); + }); +} + +export function setDuration(value: number, unit: AlertSuppressionDurationUnit): void { + act(() => { + fireEvent.input( + within(screen.getByTestId('alertSuppressionDuration')).getByTestId('interval'), + { + target: { value: value.toString() }, + } + ); + + fireEvent.change( + within(screen.getByTestId('alertSuppressionDuration')).getByTestId('timeType'), + { + target: { value: unit }, + } + ); + }); +} + +export function expectDuration(value: number, unit: AlertSuppressionDurationUnit): void { + expect( + within(screen.getByTestId('alertSuppressionDuration')).getByTestId('interval') + ).toHaveValue(value); + expect( + within(screen.getByTestId('alertSuppressionDuration')).getByTestId('timeType') + ).toHaveValue(unit); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/duration_input/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/duration_input/index.tsx similarity index 68% rename from x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/duration_input/index.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/duration_input/index.tsx index 99222756bcf26..b203cdea8f737 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/duration_input/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/duration_input/index.tsx @@ -5,10 +5,9 @@ * 2.0. */ -import { EuiFieldNumber, EuiFormRow, EuiSelect, transparentize } from '@elastic/eui'; -import React, { useCallback } from 'react'; -import styled from 'styled-components'; - +import React, { memo, useCallback } from 'react'; +import { css } from '@emotion/css'; +import { EuiFieldNumber, EuiFormRow, EuiSelect, transparentize, useEuiTheme } from '@elastic/eui'; import type { FieldHook } from '../../../../shared_imports'; import { getFieldValidityAndErrorMessage } from '../../../../shared_imports'; import * as I18n from './translations'; @@ -21,39 +20,10 @@ interface DurationInputProps { durationUnitOptions?: Array<{ value: 's' | 'm' | 'h' | 'd'; text: string }>; } -const getNumberFromUserInput = (input: string, minimumValue = 0): number | undefined => { - const number = parseInt(input, 10); - if (Number.isNaN(number)) { - return minimumValue; - } else { - return Math.max(minimumValue, Math.min(number, Number.MAX_SAFE_INTEGER)); - } -}; - -const StyledEuiFormRow = styled(EuiFormRow)` - max-width: 235px; - - .euiFormControlLayout__append { - padding-inline: 0 !important; - } - - .euiFormControlLayoutIcons { - color: ${({ theme }) => theme.eui.euiColorPrimary}; - } -`; - -const MyEuiSelect = styled(EuiSelect)` - min-width: 106px; // Preserve layout when disabled & dropdown arrow is not rendered - box-shadow: none; - background: ${({ theme }) => - transparentize(theme.eui.euiColorPrimary, 0.1)} !important; // Override focus states etc. - color: ${({ theme }) => theme.eui.euiColorPrimary}; -`; - // This component is similar to the ScheduleItem component, but instead of combining the value // and unit into a single string it keeps them separate. This makes the component simpler and // allows for easier validation of values and units in APIs as well. -const DurationInputComponent: React.FC = ({ +export const DurationInput = memo(function DurationInputComponent({ durationValueField, durationUnitField, minimumValue = 0, @@ -64,7 +34,8 @@ const DurationInputComponent: React.FC = ({ { value: 'h', text: I18n.HOURS }, ], ...props -}: DurationInputProps) => { +}: DurationInputProps): JSX.Element { + const { euiTheme } = useEuiTheme(); const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(durationValueField); const { value: durationValue, setValue: setDurationValue } = durationValueField; const { value: durationUnit, setValue: setDurationUnit } = durationUnitField; @@ -84,17 +55,40 @@ const DurationInputComponent: React.FC = ({ [minimumValue, setDurationValue] ); + const durationFormRowStyle = css` + max-width: 235px; + + .euiFormControlLayout__append { + padding-inline: 0 !important; + } + + .euiFormControlLayoutIcons { + color: ${euiTheme.colors.primary}; + } + `; + const durationUnitSelectStyle = css` + min-width: 106px; // Preserve layout when disabled & dropdown arrow is not rendered + box-shadow: none; + background: ${transparentize( + euiTheme.colors.primary, + 0.1 + )} !important; // Override focus states etc. + color: ${euiTheme.colors.primary}; + `; + // EUI missing some props const rest = { disabled: isDisabled, ...props }; return ( - + @@ -106,8 +100,16 @@ const DurationInputComponent: React.FC = ({ data-test-subj="interval" {...rest} /> - +
    ); -}; +}); + +function getNumberFromUserInput(input: string, minimumValue = 0): number | undefined { + const number = parseInt(input, 10); -export const DurationInput = React.memo(DurationInputComponent); + if (Number.isNaN(number)) { + return minimumValue; + } else { + return Math.max(minimumValue, Math.min(number, Number.MAX_SAFE_INTEGER)); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/duration_input/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/duration_input/translations.ts similarity index 82% rename from x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/duration_input/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/duration_input/translations.ts index c460d2f7198b3..51d659210c52b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/duration_input/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/duration_input/translations.ts @@ -34,3 +34,10 @@ export const DAYS = i18n.translate( defaultMessage: 'Days', } ); + +export const DURATION_UNIT_SELECTOR = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepScheduleRuleForm.durationUnitSelector', + { + defaultMessage: 'Duration unit selector', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/related_integrations/related_integrations.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/related_integrations/related_integrations.test.tsx index 960df4c7de5b9..31e139a335bee 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/related_integrations/related_integrations.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/related_integrations/related_integrations.test.tsx @@ -6,19 +6,24 @@ */ import React from 'react'; -import { - screen, - render, - act, - fireEvent, - waitFor, - waitForElementToBeRemoved, -} from '@testing-library/react'; +import { screen, render, act, fireEvent, waitFor } from '@testing-library/react'; import type { RelatedIntegration } from '../../../../../common/api/detection_engine'; import { FIELD_TYPES, Form, useForm } from '../../../../shared_imports'; import { createReactQueryWrapper } from '../../../../common/mock'; import { fleetIntegrationsApi } from '../../../fleet_integrations/api/__mocks__'; import { RelatedIntegrations } from './related_integrations'; +import { + clearEuiComboBoxSelection, + selectEuiComboBoxOption, + selectFirstEuiComboBoxOption, + showEuiComboBoxOptions, +} from '../../../../common/test/eui/combobox'; +import { + addRelatedIntegrationRow, + removeLastRelatedIntegrationRow, + setVersion, + waitForIntegrationsToBeLoaded, +} from './test_helpers'; // must match to the import in rules/related_integrations/use_integrations.tsx jest.mock('../../../fleet_integrations/api'); @@ -41,7 +46,6 @@ const COMBO_BOX_TOGGLE_BUTTON_TEST_ID = 'comboBoxToggleListButton'; const COMBO_BOX_SELECTION_TEST_ID = 'euiComboBoxPill'; const COMBO_BOX_CLEAR_BUTTON_TEST_ID = 'comboBoxClearButton'; const VERSION_INPUT_TEST_ID = 'relatedIntegrationVersionDependency'; -const REMOVE_INTEGRATION_ROW_BUTTON_TEST_ID = 'relatedIntegrationRemove'; describe('RelatedIntegrations form part', () => { beforeEach(() => { @@ -708,72 +712,6 @@ function TestForm({ initialState, onSubmit }: TestFormProps): JSX.Element { ); } -function waitForIntegrationsToBeLoaded(): Promise { - return waitForElementToBeRemoved(screen.queryAllByRole('progressbar')); -} - -function addRelatedIntegrationRow(): Promise { - return act(async () => { - fireEvent.click(screen.getByText('Add integration')); - }); -} - -function removeLastRelatedIntegrationRow(): Promise { - return act(async () => { - const lastRemoveButton = screen.getAllByTestId(REMOVE_INTEGRATION_ROW_BUTTON_TEST_ID).at(-1); - - if (!lastRemoveButton) { - throw new Error(`There are no "${REMOVE_INTEGRATION_ROW_BUTTON_TEST_ID}" found`); - } - - fireEvent.click(lastRemoveButton); - }); -} - -function showEuiComboBoxOptions(comboBoxToggleButton: HTMLElement): Promise { - fireEvent.click(comboBoxToggleButton); - - return waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); -} - -function selectEuiComboBoxOption({ - comboBoxToggleButton, - optionIndex, -}: { - comboBoxToggleButton: HTMLElement; - optionIndex: number; -}): Promise { - return act(async () => { - await showEuiComboBoxOptions(comboBoxToggleButton); - - fireEvent.click(screen.getAllByRole('option')[optionIndex]); - }); -} - -function clearEuiComboBoxSelection({ clearButton }: { clearButton: HTMLElement }): Promise { - return act(async () => { - fireEvent.click(clearButton); - }); -} - -function selectFirstEuiComboBoxOption({ - comboBoxToggleButton, -}: { - comboBoxToggleButton: HTMLElement; -}): Promise { - return selectEuiComboBoxOption({ comboBoxToggleButton, optionIndex: 0 }); -} - -function setVersion({ input, value }: { input: HTMLInputElement; value: string }): Promise { - return act(async () => { - fireEvent.input(input, { - target: { value }, - }); - }); -} - function submitForm(): Promise { return act(async () => { fireEvent.click(screen.getByText('Submit')); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/related_integrations/test_helpers.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/related_integrations/test_helpers.ts new file mode 100644 index 0000000000000..b8c51fd594e13 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/related_integrations/test_helpers.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// eslint-disable-next-line import/no-extraneous-dependencies +import { act, fireEvent, waitForElementToBeRemoved, screen } from '@testing-library/react'; + +const REMOVE_INTEGRATION_ROW_BUTTON_TEST_ID = 'relatedIntegrationRemove'; + +export function waitForIntegrationsToBeLoaded(): Promise { + return waitForElementToBeRemoved(screen.queryAllByRole('progressbar')); +} + +export function addRelatedIntegrationRow(): Promise { + return act(async () => { + fireEvent.click(screen.getByText('Add integration')); + }); +} + +export function removeLastRelatedIntegrationRow(): Promise { + return act(async () => { + const lastRemoveButton = screen.getAllByTestId(REMOVE_INTEGRATION_ROW_BUTTON_TEST_ID).at(-1); + + if (!lastRemoveButton) { + throw new Error(`There are no "${REMOVE_INTEGRATION_ROW_BUTTON_TEST_ID}" found`); + } + + fireEvent.click(lastRemoveButton); + }); +} + +export function setVersion({ + input, + value, +}: { + input: HTMLInputElement; + value: string; +}): Promise { + return act(async () => { + fireEvent.input(input, { + target: { value }, + }); + }); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/fields.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/fields.ts new file mode 100644 index 0000000000000..4956a2555bc9c --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/fields.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 THRESHOLD_ALERT_SUPPRESSION_ENABLED = 'thresholdAlertSuppressionEnabled' as const; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/index.ts new file mode 100644 index 0000000000000..67848fbd5e3b5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './threshold_alert_suppression_edit'; +export * from './fields'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/threshold_alert_suppression_edit.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/threshold_alert_suppression_edit.tsx new file mode 100644 index 0000000000000..a832bff648e8a --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/threshold_alert_suppression_edit.tsx @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; +import { EuiPanel, EuiToolTip } from '@elastic/eui'; +import { CheckBoxField } from '@kbn/es-ui-shared-plugin/static/forms/components'; +import { UseField, useFormData } from '../../../../shared_imports'; +import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from './fields'; +import { SuppressionDurationSelector } from '../alert_suppression_edit'; +import * as i18n from './translations'; + +interface ThresholdAlertSuppressionEditProps { + suppressionFieldNames: string[] | undefined; + disabled?: boolean; + disabledText?: string; +} + +export const ThresholdAlertSuppressionEdit = memo(function ThresholdAlertSuppressionEdit({ + suppressionFieldNames, + disabled, + disabledText, +}: ThresholdAlertSuppressionEditProps): JSX.Element { + const [{ [THRESHOLD_ALERT_SUPPRESSION_ENABLED]: suppressionEnabled }] = useFormData({ + watch: THRESHOLD_ALERT_SUPPRESSION_ENABLED, + }); + const content = ( + <> + + + + + + ); + + return disabled && disabledText ? ( + + {content} + + ) : ( + content + ); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/translations.tsx new file mode 100644 index 0000000000000..25b7158610b34 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation/components/threshold_alert_suppression_edit/translations.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +export const enableSuppressionForFields = (fields: string[]) => ( + {fields.join(', ')} }} + /> +); + +export const SUPPRESS_ALERTS = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.thresholdAlertSuppression.enable', + { + defaultMessage: 'Suppress alerts', + } +); + +export const THRESHOLD_SUPPRESSION_PER_RULE_EXECUTION_WARNING = i18n.translate( + 'xpack.securitySolution.ruleManagement.ruleFields.thresholdAlertSuppression.perRuleExecutionWarning', + { + defaultMessage: 'Per rule execution option is not available for Threshold rule type', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/__mocks__/use_data_views.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/__mocks__/use_data_view_list_items.ts similarity index 81% rename from x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/__mocks__/use_data_views.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/__mocks__/use_data_view_list_items.ts index 248729f1f46e7..3d2ba5d1c3724 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/__mocks__/use_data_views.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/__mocks__/use_data_view_list_items.ts @@ -5,7 +5,7 @@ * 2.0. */ -export const useDataViews = jest.fn().mockReturnValue({ +export const useDataViewListItems = jest.fn().mockReturnValue({ data: [], isFetching: false, }); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/data_view_selector_field.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/data_view_selector_field.test.tsx index 6cfdf060434b8..8648ade5164e6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/data_view_selector_field.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/data_view_selector_field/data_view_selector_field.test.tsx @@ -9,14 +9,14 @@ import React from 'react'; import { screen, render } from '@testing-library/react'; import { TestProviders, useFormFieldMock } from '../../../../common/mock'; import { DataViewSelectorField } from './data_view_selector_field'; -import { useDataViews } from './use_data_views'; +import { useDataViewListItems } from './use_data_view_list_items'; jest.mock('../../../../common/lib/kibana'); -jest.mock('./use_data_views'); +jest.mock('./use_data_view_list_items'); describe('data_view_selector', () => { it('renders correctly', () => { - (useDataViews as jest.Mock).mockReturnValue({ data: [], isFetching: false }); + (useDataViewListItems as jest.Mock).mockReturnValue({ data: [], isFetching: false }); render( { }); it('disables the combobox while data views are fetching', () => { - (useDataViews as jest.Mock).mockReturnValue({ data: [], isFetching: true }); + (useDataViewListItems as jest.Mock).mockReturnValue({ data: [], isFetching: true }); render( { title: 'logs-*', }, ]; - (useDataViews as jest.Mock).mockReturnValue({ data: dataViews, isFetching: false }); + (useDataViewListItems as jest.Mock).mockReturnValue({ data: dataViews, isFetching: false }); render( { title: 'logs-*', }, ]; - (useDataViews as jest.Mock).mockReturnValue({ data: dataViews, isFetching: false }); + (useDataViewListItems as jest.Mock).mockReturnValue({ data: dataViews, isFetching: false }); render( { }); it('displays warning on missing data view', () => { - (useDataViews as jest.Mock).mockReturnValue({ data: [], isFetching: false }); + (useDataViewListItems as jest.Mock).mockReturnValue({ data: [], isFetching: false }); render( { @@ -615,11 +615,11 @@ export const buildAlertSuppressionDescription = ( export const buildAlertSuppressionWindowDescription = ( label: string, value: Duration, - groupByRadioSelection: GroupByOptions, + alertSuppressionDuration: AlertSuppressionDurationType, ruleType: Type ): ListItems[] => { const description = - groupByRadioSelection === GroupByOptions.PerTimePeriod + alertSuppressionDuration === AlertSuppressionDurationType.PerTimePeriod ? `${value.value}${value.unit}` : i18n.ALERT_SUPPRESSION_PER_RULE_EXECUTION; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx index f5a7e39634359..de46d09065f4e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.test.tsx @@ -30,6 +30,15 @@ import { schema } from '../step_about_rule/schema'; import type { ListItems } from './types'; import type { AboutStepRule } from '../../../../detections/pages/detection_engine/rules/types'; import { createLicenseServiceMock } from '../../../../../common/license/mocks'; +import { + ALERT_SUPPRESSION_DURATION_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_UNIT_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_VALUE_FIELD_NAME, + ALERT_SUPPRESSION_FIELDS_FIELD_NAME, + ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, +} from '../../../rule_creation/components/alert_suppression_edit'; +import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../rule_creation/components/threshold_alert_suppression_edit'; jest.mock('../../../../common/lib/kibana'); @@ -575,25 +584,25 @@ describe('description_step', () => { describe('alert suppression', () => { const suppressionFields = { - groupByDuration: { - unit: 'm', - value: 50, + [ALERT_SUPPRESSION_DURATION_FIELD_NAME]: { + [ALERT_SUPPRESSION_DURATION_VALUE_FIELD_NAME]: 50, + [ALERT_SUPPRESSION_DURATION_UNIT_FIELD_NAME]: 'm', }, - groupByRadioSelection: 'per-time-period', - enableThresholdSuppression: true, - groupByFields: ['agent.name'], - suppressionMissingFields: 'suppress', + [ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME]: 'per-time-period', + [THRESHOLD_ALERT_SUPPRESSION_ENABLED]: true, + [ALERT_SUPPRESSION_FIELDS_FIELD_NAME]: ['agent.name'], + [ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME]: 'suppress', }; - describe('groupByDuration', () => { + describe(ALERT_SUPPRESSION_DURATION_FIELD_NAME, () => { ['query', 'saved_query'].forEach((ruleType) => { - test(`should be empty if groupByFields empty for ${ruleType} rule`, () => { + test(`should be empty if ${ALERT_SUPPRESSION_FIELDS_FIELD_NAME} empty for ${ruleType} rule`, () => { const result: ListItems[] = getDescriptionItem( - 'groupByDuration', + ALERT_SUPPRESSION_DURATION_FIELD_NAME, 'label', { ruleType: 'query', ...suppressionFields, - groupByFields: [], + [ALERT_SUPPRESSION_FIELDS_FIELD_NAME]: [], }, mockFilterManager, mockLicenseService @@ -604,7 +613,7 @@ describe('description_step', () => { test(`should return item for ${ruleType} rule`, () => { const result: ListItems[] = getDescriptionItem( - 'groupByDuration', + ALERT_SUPPRESSION_DURATION_FIELD_NAME, 'label', { ruleType: 'query', @@ -620,7 +629,7 @@ describe('description_step', () => { test('should return item for threshold rule', () => { const result: ListItems[] = getDescriptionItem( - 'groupByDuration', + ALERT_SUPPRESSION_DURATION_FIELD_NAME, 'label', { ruleType: 'threshold', @@ -633,14 +642,14 @@ describe('description_step', () => { expect(result[0].description).toBe('50m'); }); - test('should return item for threshold rule if groupByFields empty', () => { + test(`should return item for threshold rule if ${ALERT_SUPPRESSION_FIELDS_FIELD_NAME} empty`, () => { const result: ListItems[] = getDescriptionItem( - 'groupByDuration', + ALERT_SUPPRESSION_DURATION_FIELD_NAME, 'label', { ruleType: 'threshold', ...suppressionFields, - groupByFields: [], + [ALERT_SUPPRESSION_FIELDS_FIELD_NAME]: [], }, mockFilterManager, mockLicenseService @@ -651,12 +660,12 @@ describe('description_step', () => { test('should be empty for threshold rule if suppression not enabled', () => { const result: ListItems[] = getDescriptionItem( - 'groupByDuration', + ALERT_SUPPRESSION_DURATION_FIELD_NAME, 'label', { ruleType: 'threshold', ...suppressionFields, - enableThresholdSuppression: false, + [THRESHOLD_ALERT_SUPPRESSION_ENABLED]: false, }, mockFilterManager, mockLicenseService @@ -666,10 +675,10 @@ describe('description_step', () => { }); }); - describe('groupByFields', () => { + describe(ALERT_SUPPRESSION_FIELDS_FIELD_NAME, () => { test(`should be empty if rule type is 'threshold'`, () => { const result: ListItems[] = getDescriptionItem( - 'groupByFields', + ALERT_SUPPRESSION_FIELDS_FIELD_NAME, 'label', { ruleType: 'threshold', @@ -685,7 +694,7 @@ describe('description_step', () => { ['query', 'saved_query'].forEach((ruleType) => { test(`should return item for ${ruleType} rule`, () => { const result: ListItems[] = getDescriptionItem( - 'groupByFields', + ALERT_SUPPRESSION_FIELDS_FIELD_NAME, 'label', { ruleType, @@ -699,10 +708,10 @@ describe('description_step', () => { }); }); - describe('suppressionMissingFields', () => { + describe(ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, () => { test(`should be empty if rule type is 'threshold'`, () => { const result: ListItems[] = getDescriptionItem( - 'suppressionMissingFields', + ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, 'label', { ruleType: 'threshold', @@ -718,7 +727,7 @@ describe('description_step', () => { ['query', 'saved_query'].forEach((ruleType) => { test(`should return item for ${ruleType} rule`, () => { const result: ListItems[] = getDescriptionItem( - 'suppressionMissingFields', + ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, 'label', { ruleType, @@ -730,14 +739,14 @@ describe('description_step', () => { expect(result[0].description).toContain('Suppress'); }); - test(`should be empty if groupByFields empty for ${ruleType} rule`, () => { + test(`should be empty if ${ALERT_SUPPRESSION_FIELDS_FIELD_NAME} empty for ${ruleType} rule`, () => { const result: ListItems[] = getDescriptionItem( - 'suppressionMissingFields', + ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, 'label', { ruleType: 'query', ...suppressionFields, - groupByFields: [], + [ALERT_SUPPRESSION_FIELDS_FIELD_NAME]: [], }, mockFilterManager, mockLicenseService diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.tsx index 4676f065f4af8..657f592fe47c4 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/index.tsx @@ -65,6 +65,13 @@ import { isSuppressionRuleConfiguredWithGroupBy, isSuppressionRuleConfiguredWithDuration, } from '../../../../../common/detection_engine/utils'; +import { + ALERT_SUPPRESSION_DURATION_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME, + ALERT_SUPPRESSION_FIELDS_FIELD_NAME, + ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, +} from '../../../rule_creation/components/alert_suppression_edit'; +import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../rule_creation/components/threshold_alert_suppression_edit'; const DescriptionListContainer = styled(EuiDescriptionList)` max-width: 600px; @@ -217,7 +224,7 @@ export const getDescriptionItem = ( }); } else if (field === 'responseActions') { return []; - } else if (field === 'groupByFields') { + } else if (field === ALERT_SUPPRESSION_FIELDS_FIELD_NAME) { const ruleType: Type = get('ruleType', data); const ruleCanHaveGroupByFields = isSuppressionRuleConfiguredWithGroupBy(ruleType); @@ -226,9 +233,9 @@ export const getDescriptionItem = ( } const values: string[] = get(field, data); return buildAlertSuppressionDescription(label, values, ruleType); - } else if (field === 'groupByRadioSelection') { + } else if (field === ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME) { return []; - } else if (field === 'groupByDuration') { + } else if (field === ALERT_SUPPRESSION_DURATION_FIELD_NAME) { const ruleType: Type = get('ruleType', data); const ruleCanHaveDuration = isSuppressionRuleConfiguredWithDuration(ruleType); @@ -239,21 +246,21 @@ export const getDescriptionItem = ( // threshold rule has suppression duration without grouping fields, but suppression should be explicitly enabled by user // query rule have suppression duration only if group by fields selected const showDuration = isThresholdRule(ruleType) - ? get('enableThresholdSuppression', data) === true - : get('groupByFields', data).length > 0; + ? get(THRESHOLD_ALERT_SUPPRESSION_ENABLED, data) === true + : get(ALERT_SUPPRESSION_FIELDS_FIELD_NAME, data).length > 0; if (showDuration) { const value: Duration = get(field, data); return buildAlertSuppressionWindowDescription( label, value, - get('groupByRadioSelection', data), + get(ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME, data), ruleType ); } else { return []; } - } else if (field === 'suppressionMissingFields') { + } else if (field === ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME) { const ruleType: Type = get('ruleType', data); const ruleCanHaveSuppressionMissingFields = isSuppressionRuleConfiguredWithMissingFields(ruleType); @@ -261,7 +268,7 @@ export const getDescriptionItem = ( if (!ruleCanHaveSuppressionMissingFields) { return []; } - if (get('groupByFields', data).length > 0) { + if (get(ALERT_SUPPRESSION_FIELDS_FIELD_NAME, data).length > 0) { const value = get(field, data); return buildAlertSuppressionMissingFieldsDescription(label, value, ruleType); } else { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/translations.ts index 27dfec9818eb9..5c43b9181adcb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/description_step/translations.ts @@ -182,8 +182,8 @@ export const BUILDING_BLOCK_DESCRIPTION = i18n.translate( } ); -export const GROUP_BY_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.ruleDescription.groupByFieldsLabel', +export const ALERT_SUPPRESSION_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.ruleDescription.alertSuppressionFieldsLabel', { defaultMessage: 'Suppress alerts by', } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/multi_select_fields/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/multi_select_fields/index.tsx index d38af219fe858..8a27d2f668094 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/multi_select_fields/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/multi_select_fields/index.tsx @@ -6,11 +6,9 @@ */ import React, { useMemo } from 'react'; - -import { EuiToolTip } from '@elastic/eui'; import type { DataViewFieldBase } from '@kbn/es-query'; +import { ComboBoxField } from '@kbn/es-ui-shared-plugin/static/forms/components'; import type { FieldHook } from '../../../../shared_imports'; -import { Field } from '../../../../shared_imports'; import { FIELD_PLACEHOLDER } from './translations'; interface MultiSelectAutocompleteProps { @@ -18,7 +16,6 @@ interface MultiSelectAutocompleteProps { isDisabled: boolean; field: FieldHook; fullWidth?: boolean; - disabledText?: string; dataTestSubj?: string; } @@ -28,7 +25,6 @@ const fieldDescribedByIds = 'detectionEngineMultiSelectAutocompleteField'; export const MultiSelectAutocompleteComponent: React.FC = ({ browserFields, - disabledText, isDisabled, field, fullWidth = false, @@ -46,21 +42,15 @@ export const MultiSelectAutocompleteComponent: React.FC ); - return isDisabled ? ( - - {fieldComponent} - - ) : ( - fieldComponent - ); }; export const MultiSelectFieldsAutocomplete = React.memo(MultiSelectAutocompleteComponent); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx index bdbc01ada58ff..cc303731b26e3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_about_rule/index.test.tsx @@ -23,7 +23,7 @@ import type { } from '../../../../detections/pages/detection_engine/rules/types'; import { DataSourceType, - GroupByOptions, + AlertSuppressionDurationType, } from '../../../../detections/pages/detection_engine/rules/types'; import { fillEmptySeverityMappings } from '../../../../detections/pages/detection_engine/rules/helpers'; import { TestProviders } from '../../../../common/mock'; @@ -36,6 +36,16 @@ import { import type { FormHook } from '../../../../shared_imports'; import { useKibana as mockUseKibana } from '../../../../common/lib/kibana/__mocks__'; import { useKibana } from '../../../../common/lib/kibana'; +import { + ALERT_SUPPRESSION_DURATION_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_UNIT_FIELD_NAME, + ALERT_SUPPRESSION_DURATION_VALUE_FIELD_NAME, + ALERT_SUPPRESSION_FIELDS_FIELD_NAME, + ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME, +} from '../../../rule_creation/components/alert_suppression_edit'; +import { THRESHOLD_ALERT_SUPPRESSION_ENABLED } from '../../../rule_creation/components/threshold_alert_suppression_edit'; +import { AlertSuppressionMissingFieldsStrategyEnum } from '../../../../../common/api/detection_engine'; jest.mock('../../../../common/lib/kibana'); jest.mock('../../../../common/containers/source'); @@ -69,16 +79,17 @@ export const stepDefineStepMLRule: DefineStepRule = { timeline: { id: null, title: null }, eqlOptions: {}, dataSourceType: DataSourceType.IndexPatterns, - groupByFields: ['host.name'], - groupByRadioSelection: GroupByOptions.PerRuleExecution, - groupByDuration: { - unit: 'm', - value: 5, + [ALERT_SUPPRESSION_FIELDS_FIELD_NAME]: ['host.name'], + [ALERT_SUPPRESSION_DURATION_TYPE_FIELD_NAME]: AlertSuppressionDurationType.PerRuleExecution, + [ALERT_SUPPRESSION_DURATION_FIELD_NAME]: { + [ALERT_SUPPRESSION_DURATION_VALUE_FIELD_NAME]: 5, + [ALERT_SUPPRESSION_DURATION_UNIT_FIELD_NAME]: 'm', }, + [ALERT_SUPPRESSION_MISSING_FIELDS_FIELD_NAME]: AlertSuppressionMissingFieldsStrategyEnum.suppress, + [THRESHOLD_ALERT_SUPPRESSION_ENABLED]: false, newTermsFields: ['host.ip'], historyWindowSize: '7d', shouldLoadQueryDynamically: false, - enableThresholdSuppression: false, }; describe('StepAboutRuleComponent', () => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.test.tsx index f1dcfc74e7923..50264fffabfb8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/components/step_define_rule/index.test.tsx @@ -9,7 +9,8 @@ import React, { useEffect, useState } from 'react'; import { screen, fireEvent, render, within, act, waitFor } from '@testing-library/react'; import type { Type as RuleType } from '@kbn/securitysolution-io-ts-alerting-types'; import type { DataViewBase } from '@kbn/es-query'; -import { StepDefineRule, aggregatableFields } from '.'; +import type { FieldSpec } from '@kbn/data-plugin/common'; +import { StepDefineRule } from '.'; import type { StepDefineRuleProps } from '.'; import { mockBrowserFields } from '../../../../common/containers/source/mock'; import { useRuleFromTimeline } from '../../../../detections/containers/detection_engine/rules/use_rule_from_timeline'; @@ -25,6 +26,22 @@ import { createIndexPatternField, getSelectToggleButtonForName, } from '../../../rule_creation/components/required_fields/required_fields.test'; +import { ALERT_SUPPRESSION_FIELDS_FIELD_NAME } from '../../../rule_creation/components/alert_suppression_edit'; +import { + expectDuration, + expectSuppressionFields, + setDuration, + setDurationType, + setSuppressionFields, +} from '../../../rule_creation/components/alert_suppression_edit/test_helpers'; +import { + selectEuiComboBoxOption, + selectFirstEuiComboBoxOption, +} from '../../../../common/test/eui/combobox'; +import { + addRelatedIntegrationRow, + setVersion, +} from '../../../rule_creation/components/related_integrations/test_helpers'; // Mocks integrations jest.mock('../../../fleet_integrations/api'); @@ -48,7 +65,13 @@ jest.mock('../ai_assistant', () => { }; }); -jest.mock('../data_view_selector_field/use_data_views'); +jest.mock('../data_view_selector_field/use_data_view_list_items'); + +jest.mock('../../../../common/hooks/use_license', () => ({ + useLicense: jest.fn().mockReturnValue({ + isAtLeast: jest.fn().mockReturnValue(true), + }), +})); const mockRedirectLegacyUrl = jest.fn(); const mockGetLegacyUrlConflict = jest.fn(); @@ -149,53 +172,6 @@ jest.mock('react-redux', () => { jest.mock('../../../../detections/containers/detection_engine/rules/use_rule_from_timeline'); -test('aggregatableFields', function () { - expect( - aggregatableFields([ - { - name: 'error.message', - type: 'string', - esTypes: ['text'], - searchable: true, - aggregatable: false, - readFromDocValues: false, - }, - ]) - ).toEqual([]); -}); - -test('aggregatableFields with aggregatable: true', function () { - expect( - aggregatableFields([ - { - name: 'error.message', - type: 'string', - esTypes: ['text'], - searchable: true, - aggregatable: false, - readFromDocValues: false, - }, - { - name: 'file.path', - type: 'string', - esTypes: ['keyword'], - searchable: true, - aggregatable: true, - readFromDocValues: false, - }, - ]) - ).toEqual([ - { - name: 'file.path', - type: 'string', - esTypes: ['keyword'], - searchable: true, - aggregatable: true, - readFromDocValues: false, - }, - ]); -}); - const mockUseRuleFromTimeline = useRuleFromTimeline as jest.Mock; const onOpenTimeline = jest.fn(); @@ -218,6 +194,62 @@ describe.skip('StepDefineRule', () => { expect(screen.getByTestId('stepDefineRule')).toBeDefined(); }); + describe('alert suppression', () => { + it('persists state when switching between custom query and threshold rule types', async () => { + const mockFields: FieldSpec[] = [ + { + name: 'test-field', + type: 'string', + searchable: false, + aggregatable: true, + }, + ]; + + const { rerender } = render( + , + { + wrapper: TestProviders, + } + ); + + await setSuppressionFields(['test-field']); + setDurationType('Per time period'); + setDuration(10, 'h'); + + // switch to threshold rule type + rerender( + + ); + + expectDuration(10, 'h'); + + // switch back to custom query rule type + rerender( + + ); + + expectSuppressionFields(['test-field']); + expectDuration(10, 'h'); + }); + }); + describe('related integrations', () => { beforeEach(() => { fleetIntegrationsApi.fetchAllIntegrations.mockResolvedValue({ @@ -631,13 +663,12 @@ function TestForm({ ruleType={ruleType} index={stepDefineDefaultValue.index} threatIndex={stepDefineDefaultValue.threatIndex} - groupByFields={stepDefineDefaultValue.groupByFields} + alertSuppressionFields={stepDefineDefaultValue[ALERT_SUPPRESSION_FIELDS_FIELD_NAME]} dataSourceType={stepDefineDefaultValue.dataSourceType} shouldLoadQueryDynamically={stepDefineDefaultValue.shouldLoadQueryDynamically} queryBarTitle="" queryBarSavedId="" thresholdFields={[]} - enableThresholdSuppression={false} {...formProps} />